gwion-util
utilities for the Gwion project
Loading...
Searching...
No Matches
mpool.c
Go to the documentation of this file.
1#include "gwion_util.h"
2#ifdef USE_HELGRIND
3#include "valgrind/helgrind.h"
4#endif
5
6#define SMALL_BLK 512
7#define BIG_BLK 16
8#define MPHUGE (64 * SZ_INT)
9#define BLK(obj_sz) (obj_sz < MPHUGE ? SMALL_BLK : BIG_BLK)
10
11struct Recycle {
12 volatile struct Recycle *next;
13};
14
15struct pool {
16 uint8_t ** data;
18 volatile struct Recycle *next;
19 uint32_t obj_sz;
20 uint32_t obj_id;
21 int32_t blk_id;
22 uint32_t nblk;
23};
24
25ANN static void mp_set(struct pool *p, const uint32_t obj_sz) {
26 p->obj_sz = obj_sz;
27 p->obj_id = BLK(obj_sz) - 1;
28 p->blk_id = -1;
29 p->nblk = 1;
30 p->next = NULL;
31 p->data = (uint8_t **)xcalloc(1, sizeof(uint8_t *));
33}
34
35MemPool mempool_ini(const size_t sz) {
36 MemPool p = (MemPool)xmalloc(sizeof(struct MemPool_));
37 p->master_pool = new_pool(sizeof(struct pool));
38 p->sizes = xmalloc((log2(sz) - 1) * sizeof(size_t));
39 p->sz = 0;
40 for (size_t j = SZ_INT, k = 0; sz >= k; k = j, j <<= 1) p->sizes[p->sz++] = j;
41 p->pools = (struct pool **)xcalloc(p->sz, sizeof(struct pool *));
42 return p;
43}
44
47 for (m_uint i = mp->sz + 1; --i;) {
48 struct pool *p = mp->pools[i - 1];
49 if (p) mp_end(p);
50 }
51 xfree(mp->sizes);
53 xfree(mp->master_pool);
54 xfree(mp->pools);
55 xfree(mp);
56}
57
58static inline struct pool *mp_create(MemPool mp, const uint32_t obj_sz,
59 const uint32_t idx) {
60 struct pool *p = (struct pool *)_mp_calloc2(mp->master_pool, 0);
61 mp_set(p, obj_sz);
62 mp->pools[idx] = p;
63 return p;
64}
65
66ANN struct pool *mp_ini(MemPool mp, const uint32_t obj_sz) {
67 for (size_t i = 0; i < mp->sz; ++i) {
68 if (obj_sz <= mp->sizes[i])
69 return mp->pools[i] ?: mp_create(mp, mp->sizes[i], i);
70 }
71 return NULL;
72}
73
74void mp_end(struct pool *p) {
76 for (uint32_t i = 0; i < p->nblk && p->data[i]; ++i) xfree(p->data[i]);
77 xfree(p->data);
78}
79
80static void _realloc(struct pool *p) {
81 p->obj_id = 0;
82 if (++p->blk_id == (int32_t)p->nblk) {
83 const uint32_t nblk = p->nblk + 1;
84 p->nblk <<= 1;
85 p->data = (uint8_t **)xrealloc(p->data, sizeof(uint8_t *) * p->nblk);
86 for (uint32_t i = nblk; i < p->nblk; ++i)
87 p->data[i] = NULL;
88 }
89 p->data[p->blk_id] = (uint8_t *)xcalloc(BLK(p->obj_sz), p->obj_sz);
90}
91
92static void *__mp_calloc2(struct pool *p, const bool zero) {
93 if (p->next) {
94 volatile struct Recycle *const recycle = p->next;
95 #ifdef USE_HELGRIND
96 VALGRIND_HG_CLEAN_MEMORY(recycle, p->obj_sz);
97 #endif
98 p->next = p->next->next;
99 if (zero) memset((void*)recycle, 0, p->obj_sz);
100 return (void*)recycle;
101 }
102 if (++p->obj_id == BLK(p->obj_sz)) _realloc(p);
103 return p->data[p->blk_id] + p->obj_id * p->obj_sz;
104}
105
106void *_mp_calloc2(struct pool *p, const bool zero) {
107 gwt_lock(&p->mutex);
108 void *ret = __mp_calloc2(p, zero);
109 gwt_unlock(&p->mutex);
110 return ret;
111}
112
113void _mp_free2(struct pool *p, void *ptr) {
114 gwt_lock(&p->mutex);
115 volatile struct Recycle *next = p->next;
116#ifdef POOL_CHECK
117 memset(ptr, 0, p->obj_sz);
118#endif
119 p->next = ptr;
120 p->next->next = next;
121 gwt_unlock(&p->mutex);
122}
123
124void _mp_free(MemPool mp, const m_uint size, void *ptr) {
125 struct pool *p = mp_ini(mp, size);
126 if (p)
127 _mp_free2(p, ptr);
128 else
129 xfree(ptr);
130}
131
132struct pool *new_pool(const uint32_t obj_sz) {
133 struct pool *p = (struct pool *)xmalloc(sizeof(struct pool));
134 mp_set(p, obj_sz);
135 return p;
136}
137
138#define MP_ALLOC(name, zero, default) \
139 void *_mp_##name(MemPool mp, const m_uint size) { \
140 struct pool *p = mp_ini(mp, size); \
141 void * ret = p ? _mp_calloc2(p, zero) : (void *)default; \
142 return ret; \
143 }
144
145MP_ALLOC(malloc, 0, xmalloc(size))
146MP_ALLOC(calloc, 1, xcalloc(1, size))
147
148void *mp_realloc(MemPool mp, void *ptr, const m_uint curr, const m_uint next) {
149 void *ret = _mp_malloc(mp, next);
150 if (ret != ptr) memcpy(ret, ptr, curr);
151 mp_free2(mp, curr, ptr);
152 return ret;
153}
#define ANN
Definition defs.h:19
#define LOOP_OPTIM
Definition defs.h:34
uintptr_t m_uint
Definition gwcommon.h:11
#define SZ_INT
Definition gwcommon.h:18
meta header (use this to include the whole library)
#define BLK(obj_sz)
Definition mpool.c:9
ANN struct pool * mp_ini(MemPool mp, const uint32_t obj_sz)
Definition mpool.c:66
void * _mp_calloc2(struct pool *p, const bool zero)
Definition mpool.c:106
void mp_end(struct pool *p)
Definition mpool.c:74
static ANN void mp_set(struct pool *p, const uint32_t obj_sz)
Definition mpool.c:25
void * mp_realloc(MemPool mp, void *ptr, const m_uint curr, const m_uint next)
Definition mpool.c:148
static void * __mp_calloc2(struct pool *p, const bool zero)
Definition mpool.c:92
#define MP_ALLOC(name, zero, default)
Definition mpool.c:138
MemPool mempool_ini(const size_t sz)
Definition mpool.c:35
void _mp_free2(struct pool *p, void *ptr)
Definition mpool.c:113
void mempool_end(MemPool mp)
Definition mpool.c:45
void _mp_free(MemPool mp, const m_uint size, void *ptr)
Definition mpool.c:124
struct pool * new_pool(const uint32_t obj_sz)
Definition mpool.c:132
static void _realloc(struct pool *p)
Definition mpool.c:80
static struct pool * mp_create(MemPool mp, const uint32_t obj_sz, const uint32_t idx)
Definition mpool.c:58
#define mp_free2(p, sz, a)
Definition mpool.h:28
ANEW ANN void * _mp_malloc(MemPool, const m_uint) __attribute__((hot))
struct MemPool_ * MemPool
size_t * sizes
Definition mpool.h:11
struct pool ** pools
Definition mpool.h:10
struct pool * master_pool
Definition mpool.h:9
size_t sz
Definition mpool.h:12
volatile struct Recycle * next
Definition mpool.c:12
Definition mpool.c:15
int32_t blk_id
Definition mpool.c:21
uint8_t ** data
Definition mpool.c:16
uint32_t nblk
Definition mpool.c:22
uint32_t obj_id
Definition mpool.c:20
uint32_t obj_sz
Definition mpool.c:19
gwtlock_t mutex
Definition mpool.c:17
volatile struct Recycle * next
Definition mpool.c:18
pthread_mutex_t gwtlock_t
Definition threadpool.h:12
static ANN int gwt_unlock(gwtlock_t *lock)
Definition threadpool.h:74
static ANN void gwt_lock_end(gwtlock_t *lock)
Definition threadpool.h:95
static ANN int gwt_lock_ini(gwtlock_t *lock)
Definition threadpool.h:89
static ANN int gwt_lock(gwtlock_t *lock)
Definition threadpool.h:71
#define xfree(a)
Definition xalloc.h:28
static ANEW void * xcalloc(const m_uint n, const m_uint sz)
Definition xalloc.h:18
static ANEW void * xmalloc(const m_uint sz)
Definition xalloc.h:13
static ANEW void * xrealloc(void *p, const m_uint sz)
Definition xalloc.h:23