diff options
author | 3gg <3gg@shellblade.net> | 2023-07-16 17:39:54 -0700 |
---|---|---|
committer | 3gg <3gg@shellblade.net> | 2023-07-16 17:39:54 -0700 |
commit | 7ab7d7d5b836d2595c5dc2c6db90c489f6768246 (patch) | |
tree | d87f7b7f6f7eedbfc4eb6133369d9fb0c0cc6fb2 | |
parent | ecc2645ba4c44005ef13e33c79059de69b76551f (diff) |
Fix mem and mempool iteration.
-rw-r--r-- | mem/include/mem.h | 46 | ||||
-rw-r--r-- | mem/test/mem_test.c | 4 | ||||
-rw-r--r-- | mempool/include/mempool.h | 44 | ||||
-rw-r--r-- | mempool/test/mempool_test.c | 2 |
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 | ||
7 | DEF_MEM(test_mem, int, NUM_BLOCKS); | 7 | DEF_MEM(test_mem, int, NUM_BLOCKS) |
8 | 8 | ||
9 | static int count(test_mem* mem) { | 9 | static 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. |
28 | TEST_CASE(mem_create_dyn) { | 28 | TEST_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 | ||
7 | DEF_MEMPOOL(test_pool, int, NUM_BLOCKS); | 7 | DEF_MEMPOOL(test_pool, int, NUM_BLOCKS) |
8 | 8 | ||
9 | static int count(test_pool* pool) { | 9 | static int count(test_pool* pool) { |
10 | int count = 0; | 10 | int count = 0; |