ucx/mempool.c

changeset 17
11dffb40cd91
parent 5
88625853ae74
child 40
a95ee94b9204
equal deleted inserted replaced
16:5dbef9e07376 17:11dffb40cd91
34 #endif 34 #endif
35 #include <inttypes.h> 35 #include <inttypes.h>
36 36
37 #include "mempool.h" 37 #include "mempool.h"
38 38
39 /** Capsule for destructible memory chunks. */
39 typedef struct { 40 typedef struct {
41 /** The destructor for the memory chunk. */
40 ucx_destructor destructor; 42 ucx_destructor destructor;
43 /**
44 * First byte of the memory chunk.
45 * Note, that the address <code>&amp;c</code> is also the address
46 * of the whole memory chunk.
47 */
41 char c; 48 char c;
42 } ucx_memchunk; 49 } ucx_memchunk;
43 50
51 /** Capsule for data and its destructor. */
44 typedef struct { 52 typedef struct {
53 /** The destructor for the data. */
45 ucx_destructor destructor; 54 ucx_destructor destructor;
55 /** A pointer to the data. */
46 void *ptr; 56 void *ptr;
47 } ucx_regdestr; 57 } ucx_regdestr;
48 58
49 UCX_EXTERN void ucx_mempool_shared_destr(void* ptr) { 59 UCX_EXTERN void ucx_mempool_shared_destr(void* ptr) {
50 ucx_regdestr *rd = (ucx_regdestr*)ptr; 60 ucx_regdestr *rd = (ucx_regdestr*)ptr;
78 return EXIT_FAILURE; 88 return EXIT_FAILURE;
79 } 89 }
80 } 90 }
81 91
82 void *ucx_mempool_malloc(UcxMempool *pool, size_t n) { 92 void *ucx_mempool_malloc(UcxMempool *pool, size_t n) {
93 if (pool->ndata >= pool->size) {
94 // The hard coded 16 is documented for this function and ucx_mempool_new
95 if (ucx_mempool_chcap(pool, pool->size + 16) == EXIT_FAILURE) {
96 return NULL;
97 }
98 }
99
83 ucx_memchunk *mem = (ucx_memchunk*)malloc(sizeof(ucx_destructor) + n); 100 ucx_memchunk *mem = (ucx_memchunk*)malloc(sizeof(ucx_destructor) + n);
84 if (!mem) { 101 if (!mem) {
85 return NULL; 102 return NULL;
86 } 103 }
87
88 if (pool->ndata >= pool->size) {
89 // The hard coded 16 is documented for this function and ucx_mempool_new
90 ucx_mempool_chcap(pool, pool->size + 16);
91 }
92 104
93 mem->destructor = NULL; 105 mem->destructor = NULL;
94 pool->data[pool->ndata] = mem; 106 pool->data[pool->ndata] = mem;
95 pool->ndata++; 107 pool->ndata++;
96 108
119 return newm + sizeof(ucx_destructor); 131 return newm + sizeof(ucx_destructor);
120 } 132 }
121 } 133 }
122 fprintf(stderr, "FATAL: 0x%08" PRIxPTR" not in mpool 0x%08" PRIxPTR"\n", 134 fprintf(stderr, "FATAL: 0x%08" PRIxPTR" not in mpool 0x%08" PRIxPTR"\n",
123 (intptr_t)ptr, (intptr_t)pool); 135 (intptr_t)ptr, (intptr_t)pool);
124 exit(1); 136 exit(EXIT_FAILURE);
125 } else { 137 } else {
126 return newm + sizeof(ucx_destructor); 138 return newm + sizeof(ucx_destructor);
127 } 139 }
128 } 140 }
129 141
130 void ucx_mempool_free(UcxMempool *pool, void *ptr) { 142 void ucx_mempool_free(UcxMempool *pool, void *ptr) {
131 ucx_memchunk *chunk = (ucx_memchunk*)((char*)ptr-sizeof(ucx_destructor)); 143 ucx_memchunk *chunk = (ucx_memchunk*)((char*)ptr-sizeof(ucx_destructor));
132 for(size_t i=0 ; i<pool->ndata ; i++) { 144 for(size_t i=0 ; i<pool->ndata ; i++) {
133 if(chunk == pool->data[i]) { 145 if(chunk == pool->data[i]) {
134 if(chunk->destructor != NULL) { 146 if(chunk->destructor != NULL) {
135 chunk->destructor(&chunk->c); 147 chunk->destructor(&(chunk->c));
136 } 148 }
137 free(chunk); 149 free(chunk);
138 size_t last_index = pool->ndata - 1; 150 size_t last_index = pool->ndata - 1;
139 if(i != last_index) { 151 if(i != last_index) {
140 pool->data[i] = pool->data[last_index]; 152 pool->data[i] = pool->data[last_index];
153 pool->data[last_index] = NULL;
141 } 154 }
142 pool->ndata--; 155 pool->ndata--;
143 return; 156 return;
144 } 157 }
145 } 158 }

mercurial