1 /*
2  * Copyright (c) 2012 Travis Geiselbrecht
3  *
4  * Use of this source code is governed by a MIT-style
5  * license that can be found in the LICENSE file or at
6  * https://opensource.org/licenses/MIT
7  */
8 #include <lk/debug.h>
9 #include <assert.h>
10 #include <lk/err.h>
11 #include <lk/pow2.h>
12 #include <stdlib.h>
13 #include <lib/evlog.h>
14 
15 #define INCPTR(e, ptr, inc) \
16     modpow2((ptr) + (inc), (e)->len_pow2)
17 
evlog_init_etc(evlog_t * e,uint len,uint unitsize,uintptr_t * items)18 status_t evlog_init_etc(evlog_t *e, uint len, uint unitsize, uintptr_t *items) {
19     if (len < 2 || !ispow2(len)) {
20         return ERR_INVALID_ARGS;
21     }
22     if (unitsize < 1 || !ispow2(unitsize)) {
23         return ERR_INVALID_ARGS;
24     }
25     if (unitsize > len) {
26         return ERR_INVALID_ARGS;
27     }
28 
29     e->head = 0;
30     e->unitsize = unitsize;
31     e->len_pow2 = log2_uint(len);
32     e->items = items;
33 
34     return NO_ERROR;
35 }
36 
evlog_init(evlog_t * e,uint len,uint unitsize)37 status_t evlog_init(evlog_t *e, uint len, uint unitsize) {
38     uintptr_t *items = calloc(1, len * sizeof(uintptr_t));
39     if (!items) {
40         return ERR_NO_MEMORY;
41     }
42 
43     status_t err = evlog_init_etc(e, len, unitsize, items);
44     if (err < 0)
45         free(items);
46     return err;
47 }
48 
evlog_bump_head(evlog_t * e)49 uint evlog_bump_head(evlog_t *e) {
50     uint index = e->head;
51     e->head = INCPTR(e, e->head, e->unitsize);
52 
53     return index;
54 }
55 
evlog_dump(evlog_t * e,evlog_dump_cb cb)56 void evlog_dump(evlog_t *e, evlog_dump_cb cb) {
57     for (uint index = INCPTR(e, e->head, e->unitsize); index != e->head; index = INCPTR(e, index, e->unitsize)) {
58         cb(&e->items[index]);
59     }
60 }
61 
62 
63