5 #include <string.h> /* memset */
6 #include <stdlib.h> /* calloc() free() */
10 resize(allocator_t allocator)
12 allocator_node_t cur, next;
13 allocator_block_t block;
14 int block_capacity, type_size, node_size;
21 block_capacity = allocator->block_capacity;
22 type_size = allocator->type_size;
23 node_size = type_size + sizeof(s_allocator_node_t);
25 if(!(block = (allocator_block_t)calloc(1,sizeof(s_allocator_block_t) + (block_capacity * node_size))))
28 /* update the first block of the allocator */
29 block->next = allocator->head;
30 block->allocator = allocator;
31 allocator->head = block;
33 /* move to the last node of the block. */
34 cur = (allocator_node_t)(((byte*)(block + 1)) + ((block_capacity - 1) * node_size));
36 /* initialize all the nodes of the new block */
37 for(pos = block_capacity - 1; pos >= 0; pos--, cur = (allocator_node_t)(((byte*)next) - node_size))
44 /* allocator->free pointed now on the first node of the new bloc. */
45 allocator->free = allocator->first = next;
46 /* update the allocator capacity. */
47 allocator->capacity += block_capacity;
53 allocator_new(int block_capacity, int type_size, fn_finalize_t fn_finalize)
55 allocator_t allocator;
57 if((block_capacity <= 0) || (type_size <= 0))
63 if(!(allocator = (allocator_t)calloc(1,sizeof(s_allocator_t))))
66 /* updates allocator properties */
67 allocator->block_capacity = block_capacity;
68 allocator->type_size = type_size;
70 /* first block allocation */
72 if((errno = resize(allocator)))
78 allocator->fn_finalize = fn_finalize;
83 allocator_free(allocator_t* allocator_ptr)
85 allocator_block_t cur, next;
86 allocator_node_t node;
87 allocator_t allocator;
89 fn_finalize_t fn_finalize;
96 allocator = *allocator_ptr;
97 cur = allocator->head;
99 if(allocator->fn_finalize)
101 fn_finalize = allocator->fn_finalize;
102 node_size = allocator->type_size + sizeof(s_allocator_node_t);
107 /* type points to the first node */
108 node = (allocator_node_t)(((byte*)cur) + sizeof(s_allocator_block_t));
110 if(node->is_allocated)
112 type = (void*)(((byte*)node) + sizeof(s_allocator_node_t));
114 /* apply the fn_finalize function to the first type */
116 if((errno = (*fn_finalize)(&type)))
120 /*clear all the other types */
121 for(pos = 1; pos < allocator->block_capacity; pos++)
123 node = (allocator_node_t)(((byte*)node) + node_size);
125 if(node->is_allocated)
127 type = (void*)(((byte*)node) + sizeof(s_allocator_node_t));
129 /* apply the fn_finalize function to the first type */
131 if((errno = (*fn_finalize)(&type)))
151 free(*allocator_ptr);
152 *allocator_ptr = NULL;
158 allocator_alloc(allocator_t allocator)
160 allocator_node_t node;
168 /* all allocator memory is used, allocate a new block */
169 if(!(allocator->free))
170 if(resize(allocator))
173 node = allocator->free;
174 node->is_allocated = 1;
176 allocator->free = allocator->free->next;
179 return (void*)(((byte*)node) + sizeof(s_allocator_node_t));
183 allocator_dealloc(allocator_t allocator, void* block)
185 allocator_node_t node;
187 if(!allocator || !block)
190 if(allocator->fn_finalize)
192 if((errno = (*(allocator->fn_finalize))(&block)))
195 memset(block, 0, allocator->type_size);
196 node->is_allocated = 0;
199 /* get the node address. */
200 node = (allocator_node_t)(((byte*)block) - sizeof(s_allocator_node_t));
202 /* the node becomes the free node and the free node become the next free node.*/
203 node->next = allocator->free;
204 allocator->free = node;
211 allocator_get_size(allocator_t allocator)
219 return allocator->size;
223 allocator_get_capacity(allocator_t allocator)
231 return allocator->capacity;
235 allocator_get_type_size(allocator_t allocator)
238 if(NULL == allocator)
244 return allocator->type_size;
248 allocator_is_empty(allocator_t allocator)
250 if(NULL == allocator)
256 return !(allocator->size);
261 allocator_is_full(allocator_t allocator)
263 if(NULL == allocator)
269 return (allocator->size == allocator->capacity);
273 allocator_get_block_capacity(allocator_t allocator)
282 return allocator->block_capacity;
286 allocator_get_capacity_available(allocator_t allocator)
294 return (allocator->capacity - allocator->size);
298 allocator_clear(allocator_t allocator)
300 allocator_block_t cur;
301 allocator_node_t node;
303 int block_capacity, node_size, type_size;
304 fn_finalize_t fn_finalize;
313 if(allocator->fn_finalize)
315 fn_finalize = allocator->fn_finalize;
316 block_capacity = allocator->block_capacity;
317 type_size = allocator->type_size;
318 node_size = type_size + sizeof(s_allocator_node_t);
320 cur = allocator->head;
324 /* type points to the first node */
325 node = (allocator_node_t)(((byte*)cur) + sizeof(s_allocator_block_t));
327 if(node->is_allocated)
330 type = (void*)(((byte*)node) + sizeof(s_allocator_node_t));
332 /* apply the fn_finalize function to the first type */
334 if((errno = (*fn_finalize)(&type)))
337 memset(type, 0, type_size);
338 node->is_allocated = 0;
341 /*clear all the other types */
342 for(pos = 1; pos < block_capacity; pos++)
344 node = (allocator_node_t)(((byte*)node) + node_size);
346 if(node->is_allocated)
348 type = (void*)(((byte*)node) + sizeof(s_allocator_node_t));
350 /* apply the fn_finalize function to the first type */
352 if((errno = (*fn_finalize)(&type)))
355 memset(type, 0, type_size);
356 node->is_allocated = 0;
364 allocator->free = allocator->first;