Repository navigation
Expand file tree
/
Copy pathmemkit_helpers.h
More file actions
224 lines (196 loc) · 9.59 KB
/
Copy pathmemkit_helpers.h
File metadata and controls
224 lines (196 loc) · 9.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
#ifndef MEMKIT_HELPERS_H
#define MEMKIT_HELPERS_H
/*
* C API helpers: storage sizing, static init macros, early-return checks.
* Included via <memkit.h>; does not add code to the linked library.
*/
#include "arena.h"
#include "bitset.h"
#include "handle_pool.h"
#include "objpool.h"
#include "queue.h"
#include "ring.h"
#include "stack.h"
#include "vector.h"
#ifdef __cplusplus
extern "C" {
#endif
/* --- Storage sizing ------------------------------------------------------- */
/** Element slab size in bytes (ring, queue, vector, stack). */
[[nodiscard]] static inline size_t memkit_elem_storage_bytes(size_t elem_size, size_t capacity)
{
return elem_size * capacity;
}
#define MEMKIT_ELEM_STORAGE_BYTES(type, capacity) \
memkit_elem_storage_bytes(sizeof(type), (capacity))
/**
* Declare a properly aligned, caller-owned element buffer.
* Pass the buffer name to MEMKIT_*_INIT_STATIC macros; capacity is inferred.
*/
#define MEMKIT_ELEM_STORAGE(type, capacity, name) alignas(type) type name[(capacity)]
/* --- Early return --------------------------------------------------------- */
/** Return from void function when status is not OK. */
#define MEMKIT_RETURN_IF_NOT_OK(status_expr) \
do { \
const int _memkit_st = (int)(status_expr); \
if (_memkit_st != 0) { \
return; \
} \
} while (0)
/** Return a value when status is not OK (status must be 0 on success). */
#define MEMKIT_RETURN_VAL_IF_NOT_OK(status_expr, ret_val) \
do { \
const int _memkit_st = (int)(status_expr); \
if (_memkit_st != 0) { \
return (ret_val); \
} \
} while (0)
/* --- Static init (tier 1) ------------------------------------------------- */
#define MEMKIT_ARENA_INIT_STATIC(arena_ptr, backing) \
arena_init( \
(arena_ptr), \
&(arena_config_t){ \
.backing = (backing), \
.backing_bytes = sizeof(backing), \
})
#define MEMKIT_RING_INIT_STATIC(ring_ptr, type, buf) \
ring_init( \
(ring_ptr), \
&(ring_config_t){ \
.elem_size = sizeof(type), \
.capacity = sizeof(buf) / sizeof(type), \
.storage = (buf), \
.storage_bytes = sizeof(buf), \
})
#define MEMKIT_RING_INIT_STATIC_OVERWRITE(ring_ptr, type, buf) \
ring_init( \
(ring_ptr), \
&(ring_config_t){ \
.elem_size = sizeof(type), \
.capacity = sizeof(buf) / sizeof(type), \
.storage = (buf), \
.storage_bytes = sizeof(buf), \
.flags = RING_FLAG_OVERWRITE_ON_FULL, \
})
#define MEMKIT_QUEUE_INIT_STATIC(queue_ptr, type, buf) \
queue_init( \
(queue_ptr), \
&(queue_config_t){ \
.elem_size = sizeof(type), \
.capacity = sizeof(buf) / sizeof(type), \
.storage = (buf), \
.storage_bytes = sizeof(buf), \
})
#define MEMKIT_VECTOR_INIT_STATIC(vector_ptr, type, buf) \
vector_init( \
(vector_ptr), \
&(vector_config_t){ \
.elem_size = sizeof(type), \
.capacity = sizeof(buf) / sizeof(type), \
.storage = (buf), \
.storage_bytes = sizeof(buf), \
})
#define MEMKIT_STACK_INIT_STATIC(stack_ptr, type, buf) \
stack_init( \
(stack_ptr), \
&(stack_config_t){ \
.elem_size = sizeof(type), \
.capacity = sizeof(buf) / sizeof(type), \
.storage = (buf), \
.storage_bytes = sizeof(buf), \
})
#define MEMKIT_BITSET_INIT_STATIC(bitset_ptr, capacity, buf) \
bitset_init( \
(bitset_ptr), \
&(bitset_config_t){ \
.capacity = (capacity), \
.storage = (buf), \
.storage_bytes = sizeof(buf), \
})
/**
* Declare objpool backing for static init. Use with MEMKIT_OBJPOOL_INIT_STATIC.
* Example: MEMKIT_OBJPOOL_STORAGE(block_t, 8, pool_buf);
*/
#define MEMKIT_OBJPOOL_STORAGE(type, capacity, prefix) \
alignas(type) uint8_t prefix##_storage[objpool_storage_bytes( \
sizeof(type), \
(capacity))]; \
uint32_t prefix##_free_stack[(capacity)]; \
uint8_t prefix##_used_bits[objpool_used_bits_bytes(capacity)]
#define MEMKIT_OBJPOOL_INIT_STATIC(pool_ptr, type, capacity, prefix) \
objpool_init( \
(pool_ptr), \
&(objpool_config_t){ \
.elem_size = sizeof(type), \
.capacity = (capacity), \
.storage = prefix##_storage, \
.storage_bytes = sizeof prefix##_storage, \
.free_stack = prefix##_free_stack, \
.free_stack_bytes = sizeof prefix##_free_stack, \
.used_bits = prefix##_used_bits, \
.used_bits_bytes = sizeof prefix##_used_bits, \
})
/**
* Declare handle-pool backing for static init. Use with MEMKIT_HANDLE_POOL_INIT_STATIC.
*/
#define MEMKIT_HANDLE_POOL_STORAGE(type, capacity, prefix) \
alignas(type) uint8_t prefix##_storage[handle_pool_storage_bytes( \
sizeof(type), \
(capacity))]; \
uint16_t prefix##_generations[(capacity)]; \
uint32_t prefix##_free_stack[(capacity)]
#define MEMKIT_HANDLE_POOL_INIT_STATIC(pool_ptr, type, capacity, prefix) \
handle_pool_init( \
(pool_ptr), \
&(handle_pool_config_t){ \
.elem_size = sizeof(type), \
.capacity = (capacity), \
.storage = prefix##_storage, \
.storage_bytes = sizeof prefix##_storage, \
.generations = prefix##_generations, \
.generations_bytes = sizeof prefix##_generations, \
.free_stack = prefix##_free_stack, \
.free_stack_bytes = sizeof prefix##_free_stack, \
})
/* --- Debug strings (bring-up only) ---------------------------------------- */
[[nodiscard]] static inline const char *memkit_ring_status_string(ring_status_t status)
{
switch (status) {
case RING_OK: return "ok";
case RING_ERR_NULL: return "null";
case RING_ERR_INVALID: return "invalid";
case RING_ERR_EMPTY: return "empty";
case RING_ERR_FULL: return "full";
case RING_ERR_OOM: return "oom";
case RING_ERR_UNSUPPORTED: return "unsupported";
default: return "unknown";
}
}
[[nodiscard]] static inline const char *memkit_queue_status_string(queue_status_t status)
{
switch (status) {
case QUEUE_OK: return "ok";
case QUEUE_ERR_NULL: return "null";
case QUEUE_ERR_INVALID: return "invalid";
case QUEUE_ERR_EMPTY: return "empty";
case QUEUE_ERR_FULL: return "full";
case QUEUE_ERR_OOM: return "oom";
case QUEUE_ERR_UNSUPPORTED: return "unsupported";
default: return "unknown";
}
}
[[nodiscard]] static inline const char *memkit_arena_status_string(arena_status_t status)
{
switch (status) {
case ARENA_OK: return "ok";
case ARENA_ERR_NULL: return "null";
case ARENA_ERR_INVALID: return "invalid";
case ARENA_ERR_OOM: return "oom";
case ARENA_ERR_UNSUPPORTED: return "unsupported";
default: return "unknown";
}
}
#ifdef __cplusplus
}
#endif
#endif /* MEMKIT_HELPERS_H */