aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author3gg <3gg@shellblade.net>2023-01-23 16:54:36 -0800
committer3gg <3gg@shellblade.net>2023-01-23 16:54:36 -0800
commit007aa328fcf973b47fcfd8225ab9077cb3c45145 (patch)
tree9f1bc4db5d4edd5cd0bee634592b04408ac75b13
parentd22337cb86b196ce6a953219fa4bd46a31d144dd (diff)
Format.
-rw-r--r--list/include/list.h2
-rw-r--r--listpool/include/listpool.h57
-rw-r--r--listpool/src/listpool.c19
-rw-r--r--mempool/include/mempool.h72
4 files changed, 79 insertions, 71 deletions
diff --git a/list/include/list.h b/list/include/list.h
index b00b48b..945de28 100644
--- a/list/include/list.h
+++ b/list/include/list.h
@@ -17,5 +17,5 @@ typedef struct list {
17void list_make(list* list, size_t size); 17void list_make(list* list, size_t size);
18 18
19/// Iterates over all the items in the list. 19/// Iterates over all the items in the list.
20#define list_foreach(LIST, iter) \ 20#define list_foreach(LIST, iter) \
21 for (struct list* iter = LIST; iter; iter = iter->next) 21 for (struct list* iter = LIST; iter; iter = iter->next)
diff --git a/listpool/include/listpool.h b/listpool/include/listpool.h
index a5e4955..1711449 100644
--- a/listpool/include/listpool.h
+++ b/listpool/include/listpool.h
@@ -7,11 +7,11 @@
7#include <stdint.h> 7#include <stdint.h>
8 8
9/// Define a typed listpool of a given size. 9/// Define a typed listpool of a given size.
10#define DEF_LISTPOOL(POOL, TYPE, NUM_BLOCKS) \ 10#define DEF_LISTPOOL(POOL, TYPE, NUM_BLOCKS) \
11 typedef struct POOL { \ 11 typedef struct POOL { \
12 listpool pool; \ 12 listpool pool; \
13 list nodes[NUM_BLOCKS]; \ 13 list nodes[NUM_BLOCKS]; \
14 TYPE blocks[NUM_BLOCKS]; \ 14 TYPE blocks[NUM_BLOCKS]; \
15 } POOL; 15 } POOL;
16 16
17/// Creates a new listpool. 17/// Creates a new listpool.
@@ -20,8 +20,8 @@
20 assert(POOL); \ 20 assert(POOL); \
21 const size_t block_size = sizeof((POOL)->blocks[0]); \ 21 const size_t block_size = sizeof((POOL)->blocks[0]); \
22 const size_t num_blocks = sizeof((POOL)->blocks) / block_size; \ 22 const size_t num_blocks = sizeof((POOL)->blocks) / block_size; \
23 listpool_make_(&(POOL)->pool, (POOL)->nodes, (POOL)->blocks, num_blocks, \ 23 listpool_make_( \
24 block_size); \ 24 &(POOL)->pool, (POOL)->nodes, (POOL)->blocks, num_blocks, block_size); \
25 } 25 }
26 26
27/// Allocate a new block. 27/// Allocate a new block.
@@ -35,31 +35,31 @@
35/// Remove a value from the list. 35/// Remove a value from the list.
36/// Defined here instead of DEF_LISTPOOL_IMPL() because not all types may have 36/// Defined here instead of DEF_LISTPOOL_IMPL() because not all types may have
37/// an operator==. 37/// an operator==.
38#define listpool_remove(POOL, VAL) \ 38#define listpool_remove(POOL, VAL) \
39 { \ 39 { \
40 listpool_foreach(POOL, iter, { \ 40 listpool_foreach(POOL, iter, { \
41 if (*iter == VAL) { \ 41 if (*iter == VAL) { \
42 listpool_free(POOL, &iter); \ 42 listpool_free(POOL, &iter); \
43 break; \ 43 break; \
44 } \ 44 } \
45 }); \ 45 }); \
46 } 46 }
47 47
48/// Iterate over the used items of the pool. 48/// Iterate over the used items of the pool.
49#define listpool_foreach(POOL, ITER, BODY) \ 49#define listpool_foreach(POOL, ITER, BODY) \
50 for (list* it_ = (POOL)->pool.used; it_; it_ = it_->next) { \ 50 for (list* it_ = (POOL)->pool.used; it_; it_ = it_->next) { \
51 typeof((POOL)->blocks[0])* ITER = \ 51 typeof((POOL)->blocks[0])* ITER = \
52 &(POOL)->blocks[it_ - (POOL)->pool.nodes]; \ 52 &(POOL)->blocks[it_ - (POOL)->pool.nodes]; \
53 (void)ITER; \ 53 (void)ITER; \
54 BODY; \ 54 BODY; \
55 } 55 }
56 56
57typedef struct listpool { 57typedef struct listpool {
58 size_t block_size_bytes; 58 size_t block_size_bytes;
59 size_t num_blocks; 59 size_t num_blocks;
60 list* free; // Head of the free list. 60 list* free; // Head of the free list.
61 list* used; // Head of the used list. 61 list* used; // Head of the used list.
62 list* nodes; // Array of nodes. 62 list* nodes; // Array of nodes.
63 uint8_t* blocks; // Array of blocks; 63 uint8_t* blocks; // Array of blocks;
64} listpool; 64} listpool;
65 65
@@ -67,8 +67,9 @@ typedef struct listpool {
67/// `nodes` must have at least `num_blocks` nodes. 67/// `nodes` must have at least `num_blocks` nodes.
68/// `blocks` must be at least `num_blocks` * `block_size_bytes` bytes. 68/// `blocks` must be at least `num_blocks` * `block_size_bytes` bytes.
69/// All blocks are zeroed out for convenience. 69/// All blocks are zeroed out for convenience.
70void listpool_make_(listpool* pool, list* nodes, void* blocks, 70void listpool_make_(
71 size_t num_blocks, size_t block_size_bytes); 71 listpool* pool, list* nodes, void* blocks, size_t num_blocks,
72 size_t block_size_bytes);
72 73
73/// Allocate a new block. 74/// Allocate a new block.
74/// Return 0 if there is no memory left. 75/// Return 0 if there is no memory left.
diff --git a/listpool/src/listpool.c b/listpool/src/listpool.c
index 9c86a3b..8e49f32 100644
--- a/listpool/src/listpool.c
+++ b/listpool/src/listpool.c
@@ -2,15 +2,16 @@
2 2
3#include <string.h> 3#include <string.h>
4 4
5void listpool_make_(listpool* pool, list* nodes, void* blocks, 5void listpool_make_(
6 size_t num_blocks, size_t block_size_bytes) { 6 listpool* pool, list* nodes, void* blocks, size_t num_blocks,
7 size_t block_size_bytes) {
7 assert(pool); 8 assert(pool);
8 pool->block_size_bytes = block_size_bytes; 9 pool->block_size_bytes = block_size_bytes;
9 pool->num_blocks = num_blocks; 10 pool->num_blocks = num_blocks;
10 pool->free = &nodes[0]; 11 pool->free = &nodes[0];
11 pool->used = 0; 12 pool->used = 0;
12 pool->nodes = nodes; 13 pool->nodes = nodes;
13 pool->blocks = blocks; 14 pool->blocks = blocks;
14 list_make(nodes, num_blocks); 15 list_make(nodes, num_blocks);
15 memset(blocks, 0, num_blocks * block_size_bytes); 16 memset(blocks, 0, num_blocks * block_size_bytes);
16} 17}
@@ -69,9 +70,9 @@ void listpool_free_(listpool* pool, void** block_ptr) {
69 if (!pool->free) { 70 if (!pool->free) {
70 pool->free = item; 71 pool->free = item;
71 } else { 72 } else {
72 item->next = pool->free; 73 item->next = pool->free;
73 pool->free->prev = item; 74 pool->free->prev = item;
74 pool->free = item; 75 pool->free = item;
75 } 76 }
76 77
77 *block_ptr = 0; 78 *block_ptr = 0;
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.