aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author3gg <3gg@shellblade.net>2023-07-16 17:39:54 -0700
committer3gg <3gg@shellblade.net>2023-07-16 17:39:54 -0700
commit7ab7d7d5b836d2595c5dc2c6db90c489f6768246 (patch)
treed87f7b7f6f7eedbfc4eb6133369d9fb0c0cc6fb2
parentecc2645ba4c44005ef13e33c79059de69b76551f (diff)
Fix mem and mempool iteration.
-rw-r--r--mem/include/mem.h46
-rw-r--r--mem/test/mem_test.c4
-rw-r--r--mempool/include/mempool.h44
-rw-r--r--mempool/test/mempool_test.c2
4 files changed, 52 insertions, 44 deletions
diff --git a/mem/include/mem.h b/mem/include/mem.h
index 69f426f..b3d9157 100644
--- a/mem/include/mem.h
+++ b/mem/include/mem.h
@@ -19,19 +19,24 @@
19#include <stdint.h> 19#include <stdint.h>
20 20
21/// Define a typed memory allocator backed by a statically-allocated array. 21/// Define a typed memory allocator backed by a statically-allocated array.
22#define DEF_MEM(MEM, TYPE, NUM_BLOCKS) \ 22#define DEF_MEM(MEM, TYPE, NUM_BLOCKS) \
23 typedef struct MEM { \ 23 typedef struct MEM { \
24 Memory mem; \ 24 Memory mem; \
25 Chunk chunks[NUM_BLOCKS]; \ 25 Chunk chunks[NUM_BLOCKS]; \
26 TYPE blocks[NUM_BLOCKS]; \ 26 TYPE blocks[NUM_BLOCKS]; \
27 /* For uniformity with the dynamically-allocated pool. */ \
28 TYPE* object; \
27 } MEM; 29 } MEM;
28 30
29/// Define a typed memory allocator backed by a dynamically-allocated array. 31/// Define a typed memory allocator backed by a dynamically-allocated array.
30#define DEF_MEM_DYN(MEM, TYPE) \ 32#define DEF_MEM_DYN(MEM, TYPE) \
31 typedef struct MEM { \ 33 typedef struct MEM { \
32 Memory mem; \ 34 Memory mem; \
33 Chunk* chunks; \ 35 Chunk* chunks; \
34 TYPE* blocks; \ 36 TYPE* blocks; \
37 /* Does not point anywhere. Storing a pointer here so that we can recall \
38 * the type. */ \
39 TYPE* object; \
35 } MEM; 40 } MEM;
36 41
37/// Initialize a statically-backed memory allocator. 42/// Initialize a statically-backed memory allocator.
@@ -73,7 +78,7 @@
73/// Return a pointer to a chunk given the chunk's handle. 78/// Return a pointer to a chunk given the chunk's handle.
74/// The chunk must have been allocated. 79/// The chunk must have been allocated.
75#define mem_get_chunk(MEM, HANDLE) \ 80#define mem_get_chunk(MEM, HANDLE) \
76 ((__typeof__((MEM)->blocks[0])*)mem_get_chunk_(&(MEM)->mem, HANDLE)) 81 ((__typeof__((MEM)->object[0])*)mem_get_chunk_(&(MEM)->mem, HANDLE))
77 82
78/// Get the handle to the given chunk. 83/// Get the handle to the given chunk.
79#define mem_get_chunk_handle(MEM, CHUNK_PTR) \ 84#define mem_get_chunk_handle(MEM, CHUNK_PTR) \
@@ -87,15 +92,16 @@
87/// The caller can use 'i' as the index of the current chunk. 92/// The caller can use 'i' as the index of the current chunk.
88/// 93///
89/// It is valid to mem_free() the chunk at each step of the iteration. 94/// It is valid to mem_free() the chunk at each step of the iteration.
90#define mem_foreach(MEM, ITER, BODY) \ 95#define mem_foreach(MEM, ITER, BODY) \
91 size_t i = 0; \ 96 size_t i = 0; \
92 do { \ 97 do { \
93 if ((MEM)->chunks[i].used) { \ 98 if ((MEM)->mem.chunks[i].used) { \
94 __typeof__((MEM)->blocks[0])* ITER = &(MEM)->blocks[i]; \ 99 __typeof__((MEM)->object[0])* ITER = \
95 (void)ITER; \ 100 &(((__typeof__((MEM)->object[0])*)(MEM)->mem.blocks))[i]; \
96 BODY; \ 101 (void)ITER; \
97 } \ 102 BODY; \
98 i = (MEM)->chunks[i].next; \ 103 } \
104 i = (MEM)->chunks[i].next; \
99 } while (i); 105 } while (i);
100 106
101// ----------------------------------------------------------------------------- 107// -----------------------------------------------------------------------------
diff --git a/mem/test/mem_test.c b/mem/test/mem_test.c
index 6ab4c7c..2f242c3 100644
--- a/mem/test/mem_test.c
+++ b/mem/test/mem_test.c
@@ -4,7 +4,7 @@
4 4
5#define NUM_BLOCKS 10 5#define NUM_BLOCKS 10
6 6
7DEF_MEM(test_mem, int, NUM_BLOCKS); 7DEF_MEM(test_mem, int, NUM_BLOCKS)
8 8
9static int count(test_mem* mem) { 9static int count(test_mem* mem) {
10 int count = 0; 10 int count = 0;
@@ -27,7 +27,7 @@ TEST_CASE(mem_create) {
27// Create a dynamically-backed allocator. 27// Create a dynamically-backed allocator.
28TEST_CASE(mem_create_dyn) { 28TEST_CASE(mem_create_dyn) {
29 DEF_MEM_DYN(dyn_mem, int); 29 DEF_MEM_DYN(dyn_mem, int);
30 30
31 dyn_mem mem; 31 dyn_mem mem;
32 mem_make_dyn(&mem, NUM_BLOCKS, sizeof(int)); 32 mem_make_dyn(&mem, NUM_BLOCKS, sizeof(int));
33} 33}
diff --git a/mempool/include/mempool.h b/mempool/include/mempool.h
index 8251a70..23786b3 100644
--- a/mempool/include/mempool.h
+++ b/mempool/include/mempool.h
@@ -19,19 +19,22 @@
19#include <stdint.h> 19#include <stdint.h>
20 20
21/// Define a statically-allocated, typed pool of the given number of blocks. 21/// Define a statically-allocated, typed pool of the given number of blocks.
22#define DEF_MEMPOOL(POOL, TYPE, NUM_BLOCKS) \ 22#define DEF_MEMPOOL(POOL, TYPE, NUM_BLOCKS) \
23 typedef struct POOL { \ 23 typedef struct POOL { \
24 mempool pool; \ 24 mempool pool; \
25 BlockInfo block_info[NUM_BLOCKS]; \ 25 BlockInfo block_info[NUM_BLOCKS]; \
26 TYPE blocks[NUM_BLOCKS]; \ 26 TYPE blocks[NUM_BLOCKS]; \
27 /* For uniformity with the dynamically-allocated pool. */ \
28 TYPE* object; \
27 } POOL; 29 } POOL;
28 30
29/// Define a dynamically-allocated, typed pool. 31/// Define a dynamically-allocated, typed pool.
30#define DEF_MEMPOOL_DYN(POOL, TYPE) \ 32#define DEF_MEMPOOL_DYN(POOL, TYPE) \
31 typedef struct POOL { \ 33 typedef struct POOL { \
32 mempool pool; \ 34 mempool pool; \
33 BlockInfo* block_info; \ 35 /* Does not point anywhere. Storing a pointer here so that we can recall \
34 TYPE* blocks; \ 36 * the type. */ \
37 TYPE* object; \
35 } POOL; 38 } POOL;
36 39
37/// Initialize a statically-allocated pool. 40/// Initialize a statically-allocated pool.
@@ -74,7 +77,7 @@
74/// Return the ith block. 77/// Return the ith block.
75/// The block must have been allocated. 78/// The block must have been allocated.
76#define mempool_get_block(POOL, INDEX) \ 79#define mempool_get_block(POOL, INDEX) \
77 ((__typeof__((POOL)->blocks[0])*)mempool_get_block_(&(POOL)->pool, INDEX)) 80 ((__typeof__((POOL)->object[0])*)mempool_get_block_(&(POOL)->pool, INDEX))
78 81
79/// Get the index to the given block. 82/// Get the index to the given block.
80#define mempool_get_block_index(POOL, BLOCK_PTR) \ 83#define mempool_get_block_index(POOL, BLOCK_PTR) \
@@ -88,16 +91,15 @@
88/// 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.
89/// 92///
90/// 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.
91#define mempool_foreach(POOL, ITER, BODY) \ 94#define mempool_foreach(POOL, ITER, BODY) \
92 for (size_t i = 0; \ 95 for (size_t i = 0; i < (POOL)->pool.num_blocks; ++i) { \
93 i < (sizeof((POOL)->blocks) / sizeof(__typeof__((POOL)->blocks[0]))); \ 96 if (!(POOL)->pool.block_info[i].used) { \
94 ++i) { \ 97 continue; \
95 if (!(POOL)->block_info[i].used) { \ 98 } \
96 continue; \ 99 __typeof__((POOL)->object[0])* ITER = \
97 } \ 100 &(((__typeof__((POOL)->object[0])*)(POOL)->pool.blocks))[i]; \
98 __typeof__((POOL)->blocks[0])* ITER = &(POOL)->blocks[i]; \ 101 (void)ITER; \
99 (void)ITER; \ 102 BODY; \
100 BODY; \
101 } 103 }
102 104
103// ----------------------------------------------------------------------------- 105// -----------------------------------------------------------------------------
diff --git a/mempool/test/mempool_test.c b/mempool/test/mempool_test.c
index e6c24a4..d5ed1ea 100644
--- a/mempool/test/mempool_test.c
+++ b/mempool/test/mempool_test.c
@@ -4,7 +4,7 @@
4 4
5#define NUM_BLOCKS 10 5#define NUM_BLOCKS 10
6 6
7DEF_MEMPOOL(test_pool, int, NUM_BLOCKS); 7DEF_MEMPOOL(test_pool, int, NUM_BLOCKS)
8 8
9static int count(test_pool* pool) { 9static int count(test_pool* pool) {
10 int count = 0; 10 int count = 0;