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 */
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;
97 allocator = *allocator_ptr;
98 cur = allocator->head;
100 if(allocator->fn_finalize)
102 fn_finalize = allocator->fn_finalize;
103 node_size = allocator->type_size + sizeof(s_allocator_node_t);
108 /* type points to the first node */
109 node = (allocator_node_t)(((byte*)cur) + sizeof(s_allocator_block_t));
111 if(node->is_allocated)
113 type = (void*)(((byte*)node) + sizeof(s_allocator_node_t));
115 /* apply the fn_finalize function to the first type */
117 if((rv = (*fn_finalize)(&type)))
121 /*clear all the other types */
122 for(pos = 1; pos < allocator->block_capacity; pos++)
124 node = (allocator_node_t)(((byte*)node) + node_size);
126 if(node->is_allocated)
128 type = (void*)(((byte*)node) + sizeof(s_allocator_node_t));
130 /* apply the fn_finalize function to the first type */
132 if((rv = (*fn_finalize)(&type)))
152 free(*allocator_ptr);
153 *allocator_ptr = NULL;
159 allocator_alloc(allocator_t allocator)
161 allocator_node_t node;
169 /* all allocator memory is used, allocate a new block */
170 if(!(allocator->free))
171 if(resize(allocator))
174 node = allocator->free;
175 node->is_allocated = 1;
177 allocator->free = allocator->free->next;
180 return (void*)(((byte*)node) + sizeof(s_allocator_node_t));
184 allocator_dealloc(allocator_t allocator, void* block)
187 allocator_node_t node;
189 if(!allocator || !block)
192 if(allocator->fn_finalize)
194 if((rv = (*(allocator->fn_finalize))(&block)))
197 memset(block, 0, allocator->type_size);
198 node->is_allocated = 0;
201 /* get the node address. */
202 node = (allocator_node_t)(((byte*)block) - sizeof(s_allocator_node_t));
204 /* the node becomes the free node and the free node become the next free node.*/
205 node->next = allocator->free;
206 allocator->free = node;
213 allocator_get_size(allocator_t allocator)
221 return allocator->size;
225 allocator_get_capacity(allocator_t allocator)
233 return allocator->capacity;
237 allocator_get_type_size(allocator_t allocator)
240 if(NULL == allocator)
246 return allocator->type_size;
250 allocator_is_empty(allocator_t allocator)
252 if(NULL == allocator)
258 return !(allocator->size);
263 allocator_is_full(allocator_t allocator)
265 if(NULL == allocator)
271 return (allocator->size == allocator->capacity);
275 allocator_get_block_capacity(allocator_t allocator)
284 return allocator->block_capacity;
288 allocator_get_capacity_available(allocator_t allocator)
296 return (allocator->capacity - allocator->size);
300 allocator_clear(allocator_t allocator)
302 allocator_block_t cur;
303 allocator_node_t node;
305 int block_capacity, node_size, type_size;
306 fn_finalize_t fn_finalize;
316 if(allocator->fn_finalize)
318 fn_finalize = allocator->fn_finalize;
319 block_capacity = allocator->block_capacity;
320 type_size = allocator->type_size;
321 node_size = type_size + sizeof(s_allocator_node_t);
323 cur = allocator->head;
327 /* type points to the first node */
328 node = (allocator_node_t)(((byte*)cur) + sizeof(s_allocator_block_t));
330 if(node->is_allocated)
333 type = (void*)(((byte*)node) + sizeof(s_allocator_node_t));
335 /* apply the fn_finalize function to the first type */
337 if((rv = (*fn_finalize)(&type)))
340 memset(type, 0, type_size);
341 node->is_allocated = 0;
344 /*clear all the other types */
345 for(pos = 1; pos < block_capacity; pos++)
347 node = (allocator_node_t)(((byte*)node) + node_size);
349 if(node->is_allocated)
351 type = (void*)(((byte*)node) + sizeof(s_allocator_node_t));
353 /* apply the fn_finalize function to the first type */
355 if((rv = (*fn_finalize)(&type)))
358 memset(type, 0, type_size);
359 node->is_allocated = 0;
367 allocator->free = allocator->first;