src/mempool.c

changeset 1318
12fa1d37fe48
parent 1283
89935fea4b7c
child 1319
aa1f580f8f59
equal deleted inserted replaced
1317:eeb2fc3850e2 1318:12fa1d37fe48
49 if (pool->capacity > newcap || cx_szmul(newcap, 49 if (pool->capacity > newcap || cx_szmul(newcap,
50 sizeof(struct cx_mempool_memory_s*), &newmsize)) { 50 sizeof(struct cx_mempool_memory_s*), &newmsize)) {
51 errno = EOVERFLOW; 51 errno = EOVERFLOW;
52 return 1; 52 return 1;
53 } 53 }
54 struct cx_mempool_memory_s **newdata = realloc(pool->data, newmsize); 54 struct cx_mempool_memory_s **newdata = cxRealloc(
55 cxDefaultAllocator, pool->data, newmsize);
55 if (newdata == NULL) return 1; 56 if (newdata == NULL) return 1;
56 pool->data = newdata; 57 pool->data = newdata;
57 pool->capacity = newcap; 58 pool->capacity = newcap;
58 return 0; 59 return 0;
59 } 60 }
66 67
67 if (cx_mempool_ensure_capacity(pool, pool->size + 1)) { 68 if (cx_mempool_ensure_capacity(pool, pool->size + 1)) {
68 return NULL; 69 return NULL;
69 } 70 }
70 71
71 struct cx_mempool_memory_s *mem = malloc(sizeof(cx_destructor_func) + n); 72 struct cx_mempool_memory_s *mem = cxMalloc(
73 cxDefaultAllocator, sizeof(cx_destructor_func) + n);
72 if (mem == NULL) return NULL; 74 if (mem == NULL) return NULL;
73 75
74 mem->destructor = pool->auto_destr; 76 mem->destructor = pool->auto_destr;
75 pool->data[pool->size] = mem; 77 pool->data[pool->size] = mem;
76 pool->size++; 78 pool->size++;
101 ) { 103 ) {
102 struct cx_mempool_s *pool = p; 104 struct cx_mempool_s *pool = p;
103 105
104 struct cx_mempool_memory_s *mem, *newm; 106 struct cx_mempool_memory_s *mem, *newm;
105 mem = (struct cx_mempool_memory_s*)(((char *) ptr) - sizeof(cx_destructor_func)); 107 mem = (struct cx_mempool_memory_s*)(((char *) ptr) - sizeof(cx_destructor_func));
106 newm = realloc(mem, n + sizeof(cx_destructor_func)); 108 newm = cxRealloc(cxDefaultAllocator, mem, n + sizeof(cx_destructor_func));
107 109
108 if (newm == NULL) return NULL; 110 if (newm == NULL) return NULL;
109 if (mem != newm) { 111 if (mem != newm) {
110 for (size_t i = 0; i < pool->size; i++) { 112 for (size_t i = 0; i < pool->size; i++) {
111 if (pool->data[i] == mem) { 113 if (pool->data[i] == mem) {
132 for (size_t i = 0; i < pool->size; i++) { 134 for (size_t i = 0; i < pool->size; i++) {
133 if (mem == pool->data[i]) { 135 if (mem == pool->data[i]) {
134 if (mem->destructor) { 136 if (mem->destructor) {
135 mem->destructor(mem->c); 137 mem->destructor(mem->c);
136 } 138 }
137 free(mem); 139 cxFree(cxDefaultAllocator, mem);
138 size_t last_index = pool->size - 1; 140 size_t last_index = pool->size - 1;
139 if (i != last_index) { 141 if (i != last_index) {
140 pool->data[i] = pool->data[last_index]; 142 pool->data[i] = pool->data[last_index];
141 pool->data[last_index] = NULL; 143 pool->data[last_index] = NULL;
142 } 144 }
153 for (size_t i = 0; i < pool->size; i++) { 155 for (size_t i = 0; i < pool->size; i++) {
154 mem = pool->data[i]; 156 mem = pool->data[i];
155 if (mem->destructor) { 157 if (mem->destructor) {
156 mem->destructor(mem->c); 158 mem->destructor(mem->c);
157 } 159 }
158 free(mem); 160 cxFree(cxDefaultAllocator, mem);
159 } 161 }
160 free(pool->data); 162 cxFree(cxDefaultAllocator, pool->data);
161 free((void*) pool->allocator); 163 cxFree(cxDefaultAllocator, (void*) pool->allocator);
162 free(pool); 164 cxFree(cxDefaultAllocator, pool);
163 } 165 }
164 166
165 void cxMempoolSetDestructor( 167 void cxMempoolSetDestructor(
166 void *ptr, 168 void *ptr,
167 cx_destructor_func func 169 cx_destructor_func func
217 errno = EOVERFLOW; 219 errno = EOVERFLOW;
218 return NULL; 220 return NULL;
219 } 221 }
220 222
221 struct cx_mempool_s *pool = 223 struct cx_mempool_s *pool =
222 malloc(sizeof(struct cx_mempool_s)); 224 cxMalloc(cxDefaultAllocator, sizeof(struct cx_mempool_s));
223 if (pool == NULL) return NULL; 225 if (pool == NULL) return NULL;
224 226
225 CxAllocator *provided_allocator = malloc(sizeof(CxAllocator)); 227 CxAllocator *provided_allocator = cxMalloc(cxDefaultAllocator, sizeof(CxAllocator));
226 if (provided_allocator == NULL) { // LCOV_EXCL_START 228 if (provided_allocator == NULL) { // LCOV_EXCL_START
227 free(pool); 229 cxFree(cxDefaultAllocator, pool);
228 return NULL; 230 return NULL;
229 } // LCOV_EXCL_STOP 231 } // LCOV_EXCL_STOP
230 provided_allocator->cl = &cx_mempool_allocator_class; 232 provided_allocator->cl = &cx_mempool_allocator_class;
231 provided_allocator->data = pool; 233 provided_allocator->data = pool;
232 234
233 pool->allocator = provided_allocator; 235 pool->allocator = provided_allocator;
234 236
235 pool->data = malloc(poolsize); 237 pool->data = cxMalloc(cxDefaultAllocator, poolsize);
236 if (pool->data == NULL) { // LCOV_EXCL_START 238 if (pool->data == NULL) { // LCOV_EXCL_START
237 free(provided_allocator); 239 cxFree(cxDefaultAllocator, provided_allocator);
238 free(pool); 240 cxFree(cxDefaultAllocator, pool);
239 return NULL; 241 return NULL;
240 } // LCOV_EXCL_STOP 242 } // LCOV_EXCL_STOP
241 243
242 pool->size = 0; 244 pool->size = 0;
243 pool->capacity = capacity; 245 pool->capacity = capacity;
244 pool->auto_destr = destr; 246 pool->auto_destr = destr;
245 247
246 return pool; 248 return pool;
247 } 249 }
248 250
251 static void cx_mempool_free_transferred_allocator(void *al) {
252 cxFree(cxDefaultAllocator, al);
253 }
254
249 int cxMempoolTransfer( 255 int cxMempoolTransfer(
250 CxMempool *source, 256 CxMempool *source,
251 CxMempool *dest 257 CxMempool *dest
252 ) { 258 ) {
253 // safety check 259 // safety check
257 if (cx_mempool_ensure_capacity(dest, dest->size + source->size + 1)) { 263 if (cx_mempool_ensure_capacity(dest, dest->size + source->size + 1)) {
258 return 1; // LCOV_EXCL_LINE 264 return 1; // LCOV_EXCL_LINE
259 } 265 }
260 266
261 // allocate a replacement allocator for the source pool 267 // allocate a replacement allocator for the source pool
262 CxAllocator *new_source_allocator = malloc(sizeof(CxAllocator)); 268 CxAllocator *new_source_allocator = cxMalloc(cxDefaultAllocator, sizeof(CxAllocator));
263 if (new_source_allocator == NULL) { // LCOV_EXCL_START 269 if (new_source_allocator == NULL) { // LCOV_EXCL_START
264 return 1; 270 return 1;
265 } // LCOV_EXCL_STOP 271 } // LCOV_EXCL_STOP
266 new_source_allocator->cl = &cx_mempool_allocator_class; 272 new_source_allocator->cl = &cx_mempool_allocator_class;
267 new_source_allocator->data = source; 273 new_source_allocator->data = source;
272 278
273 // register the old allocator with the new pool 279 // register the old allocator with the new pool
274 // we have to remove const-ness for this, but that's okay here 280 // we have to remove const-ness for this, but that's okay here
275 CxAllocator *transferred_allocator = (CxAllocator*) source->allocator; 281 CxAllocator *transferred_allocator = (CxAllocator*) source->allocator;
276 transferred_allocator->data = dest; 282 transferred_allocator->data = dest;
277 cxMempoolRegister(dest, transferred_allocator, free); 283 cxMempoolRegister(dest, transferred_allocator, cx_mempool_free_transferred_allocator);
278 284
279 // prepare the source pool for re-use 285 // prepare the source pool for re-use
280 source->allocator = new_source_allocator; 286 source->allocator = new_source_allocator;
281 memset(source->data, 0, source->size * sizeof(source->data[0])); 287 memset(source->data, 0, source->size * sizeof(source->data[0]));
282 source->size = 0; 288 source->size = 0;

mercurial