Files
nob/src/base/pool.c
T

64 lines
1.9 KiB
C

#include "pool.h"
APool *apool_create_ex(Allocator *allocator, const APoolCreateOptions *options)
{
Assert(IsPow2(options->element_align));
U32 element_align = options->element_align;
if (element_align < alignof(APoolElement)) {
element_align = alignof(APoolElement);
}
U32 element_size = AlignUp(options->element_size, options->element_align);
APool *pool = allocator_push_type(allocator, APool);
Assert(pool != NULL);
pool->element_align= element_align;
pool->element_size = element_size;
pool->allocator = allocator;
pool->n_elements = 0;
pool->n_free = 0;
pool->free_list = NULL;
pool->flags = options->flags;
if (options->n_reserved != 0) {
Assert(options->n_reserved <= U32_Max / element_size );
U32 total_size = options->n_reserved * element_size;
U8 *start = allocator_push(allocator, total_size, element_align);
for (U32 i = 0; i < total_size; i += element_size) {
APoolElement *element = (APoolElement *)&start[i];
element->next = pool->free_list;
pool->free_list = element;
pool->n_elements++;
}
pool->n_free = pool->n_elements;
}
return pool;
}
void *apool_alloc(APool *pool)
{
APoolElement *element = pool->free_list;
if (element != NULL) {
pool->free_list = element->next;
pool->n_free--;
} else if((pool->flags & APoolFlag_AutoGrow) != 0) {
element = allocator_push(pool->allocator, pool->element_size, pool->element_align);
if (element != NULL) {
pool->n_elements++;
}
}
return element;
}
void apool_free(APool *pool, void *ptr)
{
if (ptr != NULL) {
APoolElement *element = (APoolElement *)ptr;
element->next = pool->free_list;
pool->free_list = element;
pool->n_free++;
}
}