aboutsummaryrefslogtreecommitdiff
path: root/mempool/include/mempool.h
diff options
context:
space:
mode:
Diffstat (limited to 'mempool/include/mempool.h')
-rw-r--r--mempool/include/mempool.h35
1 files changed, 25 insertions, 10 deletions
diff --git a/mempool/include/mempool.h b/mempool/include/mempool.h
index 23786b3..bd4d4dd 100644
--- a/mempool/include/mempool.h
+++ b/mempool/include/mempool.h
@@ -91,28 +91,43 @@
91/// The caller can use 'i' as the index of the current block. 91/// The caller can use 'i' as the index of the current block.
92/// 92///
93/// It is valid to mempool_free() the object at each step of the iteration. 93/// It is valid to mempool_free() the object at each step of the iteration.
94#define mempool_foreach(POOL, ITER, BODY) \ 94#define mempool_foreach(POOL, ITER, BODY) \
95 for (size_t i = 0; i < (POOL)->pool.num_blocks; ++i) { \ 95 { \
96 if (!(POOL)->pool.block_info[i].used) { \ 96 size_t i = (POOL)->pool.used; \
97 continue; \ 97 do { \
98 } \ 98 if ((POOL)->pool.block_info[i].used) { \
99 __typeof__((POOL)->object[0])* ITER = \ 99 __typeof__((POOL)->object[0])* ITER = \
100 &(((__typeof__((POOL)->object[0])*)(POOL)->pool.blocks))[i]; \ 100 &(((__typeof__((POOL)->object[0])*)(POOL)->pool.blocks))[i]; \
101 (void)ITER; \ 101 (void)ITER; \
102 BODY; \ 102 BODY; \
103 } \
104 const size_t next = (POOL)->pool.block_info[i].next_used; \
105 if (next == i) { \
106 break; \
107 } \
108 i = next; \
109 } while (true); \
103 } 110 }
104 111
105// ----------------------------------------------------------------------------- 112// -----------------------------------------------------------------------------
106 113
107typedef struct BlockInfo { 114typedef struct BlockInfo {
108 size_t next; /// For free blocks, points to the next free block. 115 size_t next_free; /// For free blocks, points to the next free block.
116 size_t next_used; /// For used blocks, points to the next used block.
109 bool used; 117 bool used;
110} BlockInfo; 118} BlockInfo;
111 119
120/// Memory pool.
121///
122/// 'head' and 'used' always points to a valid block (e.g., 0).
123/// The implementation must check whether the head of the lists are used/free.
124/// For example, iteration must stop when it finds the first unused block
125/// (BlockInfo.used == 0).
112typedef struct mempool { 126typedef struct mempool {
113 size_t block_size_bytes; 127 size_t block_size_bytes;
114 size_t num_blocks; 128 size_t num_blocks;
115 size_t head; /// Points to the first block in the free list. 129 size_t head; /// Points to the first block in the free list.
130 size_t used; /// Points to the first block in the used list.
116 bool dynamic; /// True if blocks and info are dynamically-allocated. 131 bool dynamic; /// True if blocks and info are dynamically-allocated.
117 BlockInfo* block_info; 132 BlockInfo* block_info;
118 uint8_t* blocks; 133 uint8_t* blocks;