-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmempool.h
78 lines (71 loc) · 6.08 KB
/
mempool.h
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
#ifndef slang_mempool_h
#define slang_mempool_h
#include <stddef.h> // size_t
#include <stdlib.h> // malloc
#include "mem.h"
// A memory pool allocator
#define MemPool(T) MemPool_GEN_##T
#define mempool_new(T) pool_new_GEN_##T
#define mempool_del(T) pool_del_GEN_##T
#define mempool_alloc(T) pool_alloc_GEN_##T
#define mempool_free(T) pool_free_GEN_##T
#define mempool_declare(T) \
\
struct MemPool(T) { \
size_t cap; \
size_t next_empty; \
union MemPool(T##_Cell) { \
size_t next_empty; \
T cell; \
} \
pool[]; \
}; \
\
struct MemPool(T) * mempool_new(T)(size_t); \
void mempool_del(T)(struct MemPool(T) *); \
\
inline T *mempool_alloc(T)(struct MemPool(T) * p) { \
if (p->next_empty >= p->cap) { \
return malloc(sizeof(struct MemPool(T))); \
} \
size_t next_empty = p->pool[p->next_empty].next_empty; \
T *result = &p->pool[p->next_empty].cell; \
p->next_empty = next_empty; \
return result; \
} \
\
inline void mempool_free(T)(struct MemPool(T) * p, T * ptr) { \
union MemPool(T##_Cell) *uptr = (union MemPool(T##_Cell) *)ptr; \
if (&p->pool[0] <= uptr && uptr < &p->pool[p->cap]) { \
ptrdiff_t idx = uptr - &p->pool[0]; \
p->pool[idx].next_empty = p->next_empty; \
p->next_empty = idx; \
} else { \
free(ptr); \
} \
} \
typedef struct MemPool(T) MemPool(T)
#define mempool_define(T) \
\
MemPool(T) * mempool_new(T)(size_t size) { \
size_t struct_size = sizeof(MemPool(T)); \
size_t cell_size = sizeof(union MemPool(T##_Cell)); \
MemPool(T) *p = mem_allocate_flex(struct_size, cell_size, size); \
if (!p) { \
return 0; \
} \
for (size_t i = 0; i < size; i++) { \
p->pool[i].next_empty = i + 1; \
} \
return p; \
} \
\
void mempool_del(T)(MemPool(T) * p) { \
size_t struct_size = sizeof(MemPool(T)); \
size_t cell_size = sizeof(union MemPool(T##_Cell)); \
mem_free_flex(p, struct_size, cell_size, p->cap); \
} \
\
extern inline T *mempool_alloc(T)(MemPool(T) *); \
extern inline void mempool_free(T)(MemPool(T) *, T *)
#endif