aboutsummaryrefslogtreecommitdiff
path: root/listpool/include
diff options
context:
space:
mode:
author3gg <3gg@shellblade.net>2023-07-13 08:22:18 -0700
committer3gg <3gg@shellblade.net>2023-07-13 08:22:18 -0700
commit9f254f0c7b03236be615b1235cf3fc765d6000ea (patch)
treef0b878ef2b431b909d9efd45c1f9ec8ed8ca54f8 /listpool/include
parentfc5886c75ab2626acbc0d7b3db475d17d2cbe01f (diff)
Add mem allocator, remove listpool.
Diffstat (limited to 'listpool/include')
-rw-r--r--listpool/include/listpool.h100
1 files changed, 0 insertions, 100 deletions
diff --git a/listpool/include/listpool.h b/listpool/include/listpool.h
deleted file mode 100644
index 85a3b27..0000000
--- a/listpool/include/listpool.h
+++ /dev/null
@@ -1,100 +0,0 @@
1#pragma once
2
3#include "list.h"
4
5#include <assert.h>
6#include <stddef.h>
7#include <stdint.h>
8
9/// Define a typed listpool of a given size.
10#define DEF_LISTPOOL(POOL, TYPE, NUM_BLOCKS) \
11 typedef struct POOL { \
12 listpool pool; \
13 list nodes[NUM_BLOCKS]; \
14 TYPE blocks[NUM_BLOCKS]; \
15 } POOL;
16
17/// Creates a new listpool.
18#define listpool_make(POOL) \
19 { \
20 assert(POOL); \
21 const size_t block_size = sizeof((POOL)->blocks[0]); \
22 const size_t num_blocks = sizeof((POOL)->blocks) / block_size; \
23 listpool_make_( \
24 &(POOL)->pool, (POOL)->nodes, (POOL)->blocks, num_blocks, block_size); \
25 }
26
27/// Allocate a new block.
28/// Return 0 if there is no memory left.
29#define listpool_alloc(POOL) listpool_alloc_(&(POOL)->pool)
30
31/// Free the block.
32/// The block pointer is conveniently set to 0.
33#define listpool_free(POOL, ITEM) listpool_free_(&(POOL)->pool, (void**)ITEM)
34
35/// Remove a value from the list.
36/// Defined here instead of DEF_LISTPOOL_IMPL() because not all types may have
37/// an operator==.
38#define listpool_remove(POOL, VAL) \
39 { \
40 listpool_foreach(POOL, iter, { \
41 if (*iter == VAL) { \
42 listpool_free(POOL, &iter); \
43 break; \
44 } \
45 }); \
46 }
47
48/// Return the ith block.
49/// The block must have been allocated.
50#define listpool_get_block(POOL, INDEX) \
51 ((typeof((POOL)->blocks[0])*)listpool_get_block_(&(POOL)->pool, INDEX))
52
53/// Get the index to the given block.
54#define listpool_get_block_index(POOL, BLOCK_PTR) \
55 listpool_get_block_index_(&(POOL)->pool, BLOCK_PTR)
56
57/// Iterate over the used items of the pool.
58///
59/// The caller can use 'i' as the index of the current block.
60///
61/// It is valid to mempool_free() the object at each step of the iteration.
62#define listpool_foreach(POOL, ITER, BODY) \
63 for (list* it_ = (POOL)->pool.used; it_; it_ = it_->next) { \
64 const size_t i = it_ - (POOL)->pool.nodes; \
65 typeof((POOL)->blocks[0])* ITER = &(POOL)->blocks[i]; \
66 (void)ITER; \
67 BODY; \
68 }
69
70typedef struct listpool {
71 size_t block_size_bytes;
72 size_t num_blocks;
73 list* free; // Head of the free list.
74 list* used; // Head of the used list.
75 list* nodes; // Array of nodes.
76 uint8_t* blocks; // Array of blocks;
77} listpool;
78
79/// Create a new list pool from a user-provided array of memory.
80/// `nodes` must have at least `num_blocks` nodes.
81/// `blocks` must be at least `num_blocks` * `block_size_bytes` bytes.
82/// All blocks are zeroed out for convenience.
83void listpool_make_(
84 listpool* pool, list* nodes, void* blocks, size_t num_blocks,
85 size_t block_size_bytes);
86
87/// Allocate a new block.
88/// Return 0 if there is no memory left.
89void* listpool_alloc_(listpool* pool);
90
91/// Free the block.
92/// The block pointer is conveniently set to 0.
93void listpool_free_(listpool* pool, void** block_ptr);
94
95/// Return the ith block.
96/// The block must have been allocated.
97void* listpool_get_block_(const listpool*, size_t block_index);
98
99/// Get the index to the given block.
100size_t listpool_get_block_index_(const listpool*, const void* block);