From ced89ff7989fde2f3d1828c9be70600d70d72e3d Mon Sep 17 00:00:00 2001 From: 3gg <3gg@shellblade.net> Date: Mon, 17 Jul 2023 09:06:14 -0700 Subject: Add used list to mempool; fix mem iteration. --- mempool/include/mempool.h | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) (limited to 'mempool/include/mempool.h') diff --git a/mempool/include/mempool.h b/mempool/include/mempool.h index 23786b3..bd4d4dd 100644 --- a/mempool/include/mempool.h +++ b/mempool/include/mempool.h @@ -91,28 +91,43 @@ /// 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 < (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; \ +#define mempool_foreach(POOL, ITER, BODY) \ + { \ + size_t i = (POOL)->pool.used; \ + do { \ + if ((POOL)->pool.block_info[i].used) { \ + __typeof__((POOL)->object[0])* ITER = \ + &(((__typeof__((POOL)->object[0])*)(POOL)->pool.blocks))[i]; \ + (void)ITER; \ + BODY; \ + } \ + const size_t next = (POOL)->pool.block_info[i].next_used; \ + if (next == i) { \ + break; \ + } \ + i = next; \ + } while (true); \ } // ----------------------------------------------------------------------------- typedef struct BlockInfo { - size_t next; /// For free blocks, points to the next free block. + size_t next_free; /// For free blocks, points to the next free block. + size_t next_used; /// For used blocks, points to the next used block. bool used; } BlockInfo; +/// Memory pool. +/// +/// 'head' and 'used' always points to a valid block (e.g., 0). +/// The implementation must check whether the head of the lists are used/free. +/// For example, iteration must stop when it finds the first unused block +/// (BlockInfo.used == 0). typedef struct mempool { size_t block_size_bytes; size_t num_blocks; size_t head; /// Points to the first block in the free list. + size_t used; /// Points to the first block in the used list. bool dynamic; /// True if blocks and info are dynamically-allocated. BlockInfo* block_info; uint8_t* blocks; -- cgit v1.2.3