From 7ab7d7d5b836d2595c5dc2c6db90c489f6768246 Mon Sep 17 00:00:00 2001 From: 3gg <3gg@shellblade.net> Date: Sun, 16 Jul 2023 17:39:54 -0700 Subject: Fix mem and mempool iteration. --- mem/include/mem.h | 46 +++++++++++++++++++++++++-------------------- mem/test/mem_test.c | 4 ++-- mempool/include/mempool.h | 44 ++++++++++++++++++++++--------------------- 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 @@ #include /// Define a typed memory allocator backed by a statically-allocated array. -#define DEF_MEM(MEM, TYPE, NUM_BLOCKS) \ - typedef struct MEM { \ - Memory mem; \ - Chunk chunks[NUM_BLOCKS]; \ - TYPE blocks[NUM_BLOCKS]; \ +#define DEF_MEM(MEM, TYPE, NUM_BLOCKS) \ + typedef struct MEM { \ + Memory mem; \ + Chunk chunks[NUM_BLOCKS]; \ + TYPE blocks[NUM_BLOCKS]; \ + /* For uniformity with the dynamically-allocated pool. */ \ + TYPE* object; \ } MEM; /// Define a typed memory allocator backed by a dynamically-allocated array. -#define DEF_MEM_DYN(MEM, TYPE) \ - typedef struct MEM { \ - Memory mem; \ - Chunk* chunks; \ - TYPE* blocks; \ +#define DEF_MEM_DYN(MEM, TYPE) \ + typedef struct MEM { \ + Memory mem; \ + Chunk* chunks; \ + TYPE* blocks; \ + /* Does not point anywhere. Storing a pointer here so that we can recall \ + * the type. */ \ + TYPE* object; \ } MEM; /// Initialize a statically-backed memory allocator. @@ -73,7 +78,7 @@ /// Return a pointer to a chunk given the chunk's handle. /// The chunk must have been allocated. #define mem_get_chunk(MEM, HANDLE) \ - ((__typeof__((MEM)->blocks[0])*)mem_get_chunk_(&(MEM)->mem, HANDLE)) + ((__typeof__((MEM)->object[0])*)mem_get_chunk_(&(MEM)->mem, HANDLE)) /// Get the handle to the given chunk. #define mem_get_chunk_handle(MEM, CHUNK_PTR) \ @@ -87,15 +92,16 @@ /// The caller can use 'i' as the index of the current chunk. /// /// It is valid to mem_free() the chunk at each step of the iteration. -#define mem_foreach(MEM, ITER, BODY) \ - size_t i = 0; \ - do { \ - if ((MEM)->chunks[i].used) { \ - __typeof__((MEM)->blocks[0])* ITER = &(MEM)->blocks[i]; \ - (void)ITER; \ - BODY; \ - } \ - i = (MEM)->chunks[i].next; \ +#define mem_foreach(MEM, ITER, BODY) \ + size_t i = 0; \ + do { \ + if ((MEM)->mem.chunks[i].used) { \ + __typeof__((MEM)->object[0])* ITER = \ + &(((__typeof__((MEM)->object[0])*)(MEM)->mem.blocks))[i]; \ + (void)ITER; \ + BODY; \ + } \ + i = (MEM)->chunks[i].next; \ } while (i); // ----------------------------------------------------------------------------- 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 @@ #define NUM_BLOCKS 10 -DEF_MEM(test_mem, int, NUM_BLOCKS); +DEF_MEM(test_mem, int, NUM_BLOCKS) static int count(test_mem* mem) { int count = 0; @@ -27,7 +27,7 @@ TEST_CASE(mem_create) { // Create a dynamically-backed allocator. TEST_CASE(mem_create_dyn) { DEF_MEM_DYN(dyn_mem, int); - + dyn_mem mem; mem_make_dyn(&mem, NUM_BLOCKS, sizeof(int)); } 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 @@ #include /// Define a statically-allocated, typed pool of the given number of blocks. -#define DEF_MEMPOOL(POOL, TYPE, NUM_BLOCKS) \ - typedef struct POOL { \ - mempool pool; \ - BlockInfo block_info[NUM_BLOCKS]; \ - TYPE blocks[NUM_BLOCKS]; \ +#define DEF_MEMPOOL(POOL, TYPE, NUM_BLOCKS) \ + typedef struct POOL { \ + mempool pool; \ + BlockInfo block_info[NUM_BLOCKS]; \ + TYPE blocks[NUM_BLOCKS]; \ + /* For uniformity with the dynamically-allocated pool. */ \ + TYPE* object; \ } POOL; /// Define a dynamically-allocated, typed pool. -#define DEF_MEMPOOL_DYN(POOL, TYPE) \ - typedef struct POOL { \ - mempool pool; \ - BlockInfo* block_info; \ - TYPE* blocks; \ +#define DEF_MEMPOOL_DYN(POOL, TYPE) \ + typedef struct POOL { \ + mempool pool; \ + /* Does not point anywhere. Storing a pointer here so that we can recall \ + * the type. */ \ + TYPE* object; \ } POOL; /// Initialize a statically-allocated pool. @@ -74,7 +77,7 @@ /// Return the ith block. /// The block must have been allocated. #define mempool_get_block(POOL, INDEX) \ - ((__typeof__((POOL)->blocks[0])*)mempool_get_block_(&(POOL)->pool, INDEX)) + ((__typeof__((POOL)->object[0])*)mempool_get_block_(&(POOL)->pool, INDEX)) /// Get the index to the given block. #define mempool_get_block_index(POOL, BLOCK_PTR) \ @@ -88,16 +91,15 @@ /// The caller can use 'i' as the index of the current block. /// /// It is valid to mempool_free() the object at each step of the iteration. -#define mempool_foreach(POOL, ITER, BODY) \ - for (size_t i = 0; \ - i < (sizeof((POOL)->blocks) / sizeof(__typeof__((POOL)->blocks[0]))); \ - ++i) { \ - if (!(POOL)->block_info[i].used) { \ - continue; \ - } \ - __typeof__((POOL)->blocks[0])* ITER = &(POOL)->blocks[i]; \ - (void)ITER; \ - BODY; \ +#define mempool_foreach(POOL, ITER, BODY) \ + for (size_t i = 0; i < (POOL)->pool.num_blocks; ++i) { \ + if (!(POOL)->pool.block_info[i].used) { \ + continue; \ + } \ + __typeof__((POOL)->object[0])* ITER = \ + &(((__typeof__((POOL)->object[0])*)(POOL)->pool.blocks))[i]; \ + (void)ITER; \ + BODY; \ } // ----------------------------------------------------------------------------- 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 @@ #define NUM_BLOCKS 10 -DEF_MEMPOOL(test_pool, int, NUM_BLOCKS); +DEF_MEMPOOL(test_pool, int, NUM_BLOCKS) static int count(test_pool* pool) { int count = 0; -- cgit v1.2.3