Add parlib/common.h
[akaros.git] / user / parlib / include / pool.h
1 /* See COPYRIGHT for copyright information. */
2 /* Kevin Klues <klueska@cs.berkeley.edu>        */
3
4 #ifndef PARLIB_POOL_H
5 #define PARLIB_POOL_H
6
7 #include <string.h>
8
9 __BEGIN_DECLS
10
11 #define POOL_TYPE_DEFINE(_type, p, sz)                                                \
12 typedef struct struct_##p {                                                             \
13         uint32_t size;                                                         \
14         uint32_t free;                                                         \
15         uint32_t index;                                                        \
16         _type *queue[(sz)];                                                       \
17         _type pool[(sz)];                                                         \
18 } p##_t;
19
20 #define POOL_INIT(p, sz)                                                       \
21 ({                                                                             \
22         (p)->size = (sz);                                                          \
23         (p)->free = (sz);                                                          \
24         (p)->index = 0;                                                            \
25         memset((p)->pool, 0, (sz) * sizeof((p)->pool[0]));                         \
26         for(int i=0; i<(p)->size; i++) {                                           \
27                 (p)->queue[i] = &((p)->pool[i]);                                       \
28         }                                                                          \
29 })
30 // removed unnecessary (p)->queue[(p)->index] = NULL;
31 #define POOL_GET(p)                                            \
32 ({                                                             \
33         void* rval = NULL;                                         \
34         if((p)->free) {                                            \
35                 rval = (p)->queue[(p)->index];                         \
36                 (p)->free--;                                           \
37                 (p)->index++;                                          \
38                 if((p)->index == (p)->size) {                          \
39                 (p)->index = 0;                                    \
40         }                                                      \
41         }                                                          \
42         rval;                                                      \
43 })
44
45 // emptyIndex is also the first element that has been allocated, iterate thru to index-1
46
47 #define POOL_FOR_EACH(p, func)                                                                  \
48 ({                                                                                                                              \
49         int emptyIndex = ((p)->index + (p)->free);                  \
50         if (emptyIndex >= (p)->size) {                                          \
51                 emptyIndex -= (p)->size;                                        \
52         }                                                                   \
53         for(int _i = emptyIndex;  _i < (p)->index; _i++){                       \
54                 func((p)->queue[_i]);                                                           \
55         }                                                                                                                       \
56 })                                                                                                                              \
57
58 #define POOL_PUT(p, val)                                                       \
59 ({                                                                             \
60         int rval = -1;                                                            \
61         if((p)->free < (p)->size) {                                           \
62                 int emptyIndex = ((p)->index + (p)->free);                     \
63                 if (emptyIndex >= (p)->size) {                                 \
64                         emptyIndex -= (p)->size;                               \
65                 }                                                              \
66                 (p)->queue[emptyIndex] = val;                                  \
67                 (p)->free++;                                                   \
68                 rval = 1;                                                             \
69         }                                                                      \
70         rval;                                                                 \
71 })
72
73 #define POOL_EMPTY(p) ((p)->free == 0)
74 #define POOL_SIZE(p) ((p)->free)
75 #define POOL_MAX_SIZE(p) ((p)->size)
76
77 __END_DECLS
78
79 #endif /* PARLIB_POOL_H */