aboutsummaryrefslogtreecommitdiff
path: root/mempool
diff options
context:
space:
mode:
Diffstat (limited to 'mempool')
-rw-r--r--mempool/include/mempool.h72
1 files changed, 39 insertions, 33 deletions
diff --git a/mempool/include/mempool.h b/mempool/include/mempool.h
index 41d56e5..f2b20b9 100644
--- a/mempool/include/mempool.h
+++ b/mempool/include/mempool.h
@@ -6,21 +6,22 @@
6#include <stdint.h> 6#include <stdint.h>
7 7
8/// Define a typed mempool of the given number of blocks. 8/// Define a typed mempool of the given number of blocks.
9#define DEF_MEMPOOL(POOL, TYPE, NUM_BLOCKS) \ 9#define DEF_MEMPOOL(POOL, TYPE, NUM_BLOCKS) \
10 typedef struct POOL { \ 10 typedef struct POOL { \
11 mempool pool; \ 11 mempool pool; \
12 BlockInfo block_info[NUM_BLOCKS]; \ 12 BlockInfo block_info[NUM_BLOCKS]; \
13 TYPE blocks[NUM_BLOCKS]; \ 13 TYPE blocks[NUM_BLOCKS]; \
14 } POOL; 14 } POOL;
15 15
16/// Create a new pool. 16/// Create a new pool.
17#define mempool_make(POOL) \ 17#define mempool_make(POOL) \
18 { \ 18 { \
19 assert(POOL); \ 19 assert(POOL); \
20 const size_t block_size = sizeof((POOL)->blocks[0]); \ 20 const size_t block_size = sizeof((POOL)->blocks[0]); \
21 const size_t num_blocks = sizeof((POOL)->blocks) / block_size; \ 21 const size_t num_blocks = sizeof((POOL)->blocks) / block_size; \
22 mempool_make_(&(POOL)->pool, (POOL)->block_info, (POOL)->blocks, \ 22 mempool_make_( \
23 num_blocks, block_size); \ 23 &(POOL)->pool, (POOL)->block_info, (POOL)->blocks, num_blocks, \
24 block_size); \
24 } 25 }
25 26
26/// Allocate a new block. 27/// Allocate a new block.
@@ -29,30 +30,34 @@
29 30
30/// Free the block. 31/// Free the block.
31/// The block pointer is conveniently set to 0. 32/// The block pointer is conveniently set to 0.
32#define mempool_free(POOL, BLOCK_PTR) \ 33#define mempool_free(POOL, BLOCK_PTR) \
33 assert(*BLOCK_PTR); \ 34 assert(*BLOCK_PTR); \
34 mempool_free_(&(POOL)->pool, (void**)BLOCK_PTR) 35 mempool_free_(&(POOL)->pool, (void**)BLOCK_PTR)
35 36
36/// Return the ith block. 37/// Return the ith block.
37/// The block must have been allocated. 38/// The block must have been allocated.
38#define mempool_get_block(POOL, INDEX) \ 39#define mempool_get_block(POOL, INDEX) \
39 ((typeof((POOL)->blocks[0])*)mempool_get_block_(&(POOL)->pool, INDEX)) 40 ((typeof((POOL)->blocks[0])*)mempool_get_block_(&(POOL)->pool, INDEX))
40 41
41/// Get the index to the given block. 42/// Get the index to the given block.
42#define mempool_get_block_index(POOL, BLOCK_PTR) \ 43#define mempool_get_block_index(POOL, BLOCK_PTR) \
43 mempool_get_block_index_(&(POOL)->pool, BLOCK_PTR) 44 mempool_get_block_index_(&(POOL)->pool, BLOCK_PTR)
44 45
45/// Iterate over the used blocks of the pool. 46/// Iterate over the used blocks of the pool.
46#define mempool_foreach(POOL, ITER, BODY) \ 47///
47 for (size_t i = 0; \ 48/// The caller can use 'i' as the index of the current block.
48 i < (sizeof((POOL)->blocks) / sizeof(typeof((POOL)->blocks[0]))); \ 49///
49 ++i) { \ 50/// It is valid to mempool_free() the object at each step of the iteration.
50 if (!(POOL)->block_info[i].used) { \ 51#define mempool_foreach(POOL, ITER, BODY) \
51 continue; \ 52 for (size_t i = 0; \
52 } \ 53 i < (sizeof((POOL)->blocks) / sizeof(typeof((POOL)->blocks[0]))); \
53 typeof((POOL)->blocks[0])* ITER = &(POOL)->blocks[i]; \ 54 ++i) { \
54 (void)ITER; \ 55 if (!(POOL)->block_info[i].used) { \
55 BODY; \ 56 continue; \
57 } \
58 typeof((POOL)->blocks[0])* ITER = &(POOL)->blocks[i]; \
59 (void)ITER; \
60 BODY; \
56 } 61 }
57 62
58typedef struct BlockInfo { 63typedef struct BlockInfo {
@@ -60,20 +65,21 @@ typedef struct BlockInfo {
60} BlockInfo; 65} BlockInfo;
61 66
62typedef struct mempool { 67typedef struct mempool {
63 size_t block_size_bytes; 68 size_t block_size_bytes;
64 size_t num_blocks; 69 size_t num_blocks;
65 size_t next_free_block; 70 size_t next_free_block;
66 bool full; 71 bool full;
67 BlockInfo* block_info; 72 BlockInfo* block_info;
68 uint8_t* blocks; 73 uint8_t* blocks;
69} mempool; 74} mempool;
70 75
71/// Create a pool allocator from user-provided memory. 76/// Create a pool allocator from user-provided memory.
72/// `BlockInfo` must hold at least `num_blocks` entries. 77/// `BlockInfo` must hold at least `num_blocks` entries.
73/// `blocks` must be at least `num_blocks` * `block_size_bytes` bytes. 78/// `blocks` must be at least `num_blocks` * `block_size_bytes` bytes.
74/// All blocks are zeroed out for convenience. 79/// All blocks are zeroed out for convenience.
75void mempool_make_(mempool*, BlockInfo*, void* blocks, size_t num_blocks, 80void mempool_make_(
76 size_t block_size_bytes); 81 mempool*, BlockInfo*, void* blocks, size_t num_blocks,
82 size_t block_size_bytes);
77 83
78/// Allocate a new block. 84/// Allocate a new block.
79/// Return 0 if there is no memory left. 85/// Return 0 if there is no memory left.