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