Wed, 27 Feb 2013 13:30:21 +0100
added gnu++11 support
1 /*
2 *
3 */
5 #include <stdlib.h>
6 #include <string.h>
7 #include <stdio.h>
8 #ifdef __cplusplus
9 #define __STDC_FORMAT_MACROS
10 #endif
11 #include <inttypes.h>
13 #include "mempool.h"
15 typedef struct {
16 ucx_destructor destructor;
17 char c;
18 } ucx_memchunk;
20 typedef struct {
21 ucx_destructor destructor;
22 void *ptr;
23 } ucx_regdestr;
25 void ucx_mempool_shared_destr(void* ptr) {
26 ucx_regdestr *rd = (ucx_regdestr*)ptr;
27 rd->destructor(rd->ptr);
28 }
30 UcxMempool *ucx_mempool_new(size_t n) {
31 UcxMempool *pool = (UcxMempool*)malloc(sizeof(UcxMempool));
32 if (pool == NULL) return NULL;
34 pool->data = (void**) malloc(n * sizeof(void*));
35 if (pool->data == NULL) {
36 free(pool);
37 return NULL;
38 }
40 pool->ndata = 0;
41 pool->size = n;
42 return pool;
43 }
45 int ucx_mempool_chcap(UcxMempool *pool, size_t newcap) {
46 void **data = (void**) realloc(pool->data, newcap*sizeof(void*));
47 if (data == NULL) {
48 return 1;
49 } else {
50 pool->data = data;
51 pool->size = newcap;
52 return EXIT_SUCCESS;
53 }
54 }
56 void *ucx_mempool_malloc(UcxMempool *pool, size_t n) {
57 ucx_memchunk *mem = (ucx_memchunk*)malloc(sizeof(ucx_destructor) + n);
58 if (mem == NULL) return NULL;
60 if (pool->ndata >= pool->size) {
61 ucx_mempool_chcap(pool, pool->size + 16);
62 }
64 mem->destructor = NULL;
65 pool->data[pool->ndata] = mem;
66 pool->ndata++;
68 return &mem->c;
69 }
71 void *ucx_mempool_calloc(UcxMempool *pool, size_t nelem, size_t elsize) {
72 void *ptr = ucx_mempool_malloc(pool, nelem*elsize);
73 if(ptr == NULL) {
74 return NULL;
75 }
76 memset(ptr, 0, nelem * elsize);
77 return ptr;
78 }
80 void *ucx_mempool_realloc(UcxMempool *pool, void *ptr, size_t n) {
81 char *mem = ((char*)ptr) - sizeof(ucx_destructor);
82 char *newm = (char*) realloc(mem, n + sizeof(ucx_destructor));
83 if (newm == NULL) return NULL;
84 if (mem != newm) {
85 for(size_t i=0 ; i < pool->ndata ; i++) {
86 if(pool->data[i] == mem) {
87 pool->data[i] = newm;
88 return newm + sizeof(ucx_destructor);
89 }
90 }
91 fprintf(stderr, "FATAL: 0x%08" PRIxPTR" not in mpool 0x%08" PRIxPTR"\n",
92 (intptr_t)ptr, (intptr_t)pool);
93 exit(1);
94 } else {
95 return newm + sizeof(ucx_destructor);
96 }
97 }
99 void ucx_mempool_free(UcxMempool *pool) {
100 ucx_memchunk *chunk;
101 for(size_t i=0 ; i<pool->ndata ; i++) {
102 chunk = (ucx_memchunk*) pool->data[i];
103 if(chunk->destructor != NULL) {
104 chunk->destructor(&chunk->c);
105 }
106 free(chunk);
107 }
108 free(pool->data);
109 free(pool);
110 }
112 void ucx_mempool_set_destr(void *ptr, ucx_destructor func) {
113 *(ucx_destructor*)((char*)ptr-sizeof(ucx_destructor)) = func;
114 }
116 void ucx_mempool_reg_destr(UcxMempool *pool, void *ptr, ucx_destructor destr) {
117 ucx_regdestr *rd = (ucx_regdestr*)ucx_mempool_malloc(
118 pool,
119 sizeof(ucx_regdestr));
120 rd->destructor = destr;
121 rd->ptr = ptr;
122 ucx_mempool_set_destr(rd, ucx_mempool_shared_destr);
123 }