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.h91
1 files changed, 91 insertions, 0 deletions
diff --git a/mempool/include/mempool.h b/mempool/include/mempool.h
new file mode 100644
index 0000000..41d56e5
--- /dev/null
+++ b/mempool/include/mempool.h
@@ -0,0 +1,91 @@
1#pragma once
2
3#include <assert.h>
4#include <stdbool.h>
5#include <stddef.h>
6#include <stdint.h>
7
8/// Define a typed mempool of the given number of blocks.
9#define DEF_MEMPOOL(POOL, TYPE, NUM_BLOCKS) \
10 typedef struct POOL { \
11 mempool pool; \
12 BlockInfo block_info[NUM_BLOCKS]; \
13 TYPE blocks[NUM_BLOCKS]; \
14 } POOL;
15
16/// Create a new pool.
17#define mempool_make(POOL) \
18 { \
19 assert(POOL); \
20 const size_t block_size = sizeof((POOL)->blocks[0]); \
21 const size_t num_blocks = sizeof((POOL)->blocks) / block_size; \
22 mempool_make_(&(POOL)->pool, (POOL)->block_info, (POOL)->blocks, \
23 num_blocks, block_size); \
24 }
25
26/// Allocate a new block.
27/// Return 0 if there is no memory left.
28#define mempool_alloc(POOL) mempool_alloc_(&(POOL)->pool)
29
30/// Free the block.
31/// The block pointer is conveniently set to 0.
32#define mempool_free(POOL, BLOCK_PTR) \
33 assert(*BLOCK_PTR); \
34 mempool_free_(&(POOL)->pool, (void**)BLOCK_PTR)
35
36/// Return the ith block.
37/// The block must have been allocated.
38#define mempool_get_block(POOL, INDEX) \
39 ((typeof((POOL)->blocks[0])*)mempool_get_block_(&(POOL)->pool, INDEX))
40
41/// Get the index to the given block.
42#define mempool_get_block_index(POOL, BLOCK_PTR) \
43 mempool_get_block_index_(&(POOL)->pool, BLOCK_PTR)
44
45/// Iterate over the used blocks of the pool.
46#define mempool_foreach(POOL, ITER, BODY) \
47 for (size_t i = 0; \
48 i < (sizeof((POOL)->blocks) / sizeof(typeof((POOL)->blocks[0]))); \
49 ++i) { \
50 if (!(POOL)->block_info[i].used) { \
51 continue; \
52 } \
53 typeof((POOL)->blocks[0])* ITER = &(POOL)->blocks[i]; \
54 (void)ITER; \
55 BODY; \
56 }
57
58typedef struct BlockInfo {
59 bool used;
60} BlockInfo;
61
62typedef struct mempool {
63 size_t block_size_bytes;
64 size_t num_blocks;
65 size_t next_free_block;
66 bool full;
67 BlockInfo* block_info;
68 uint8_t* blocks;
69} mempool;
70
71/// Create a pool allocator from user-provided memory.
72/// `BlockInfo` must hold at least `num_blocks` entries.
73/// `blocks` must be at least `num_blocks` * `block_size_bytes` bytes.
74/// All blocks are zeroed out for convenience.
75void mempool_make_(mempool*, BlockInfo*, void* blocks, size_t num_blocks,
76 size_t block_size_bytes);
77
78/// Allocate a new block.
79/// Return 0 if there is no memory left.
80void* mempool_alloc_(mempool*);
81
82/// Free the block.
83/// The block pointer is conveniently set to 0.
84void mempool_free_(mempool*, void** block_ptr);
85
86/// Return the ith block.
87/// The block must have been allocated.
88void* mempool_get_block_(const mempool*, size_t block_index);
89
90/// Get the index to the given block.
91size_t mempool_get_block_index_(const mempool*, const void* block);