Kaltenberg/modules/utility/src-c/allocation/pool.c

72 lines
1.9 KiB
C
Raw Normal View History

#include <voxula/internals/utility/allocation.h>
#include <voxula/internals/utility/math.h>
#include <stdlib.h>
void vx_reset_pool_allocation(vx_pool_s *pool, uint32_t slot_size)
{
uint32_t slot_index = 0;
while(slot_index > pool->capacity)
{
vx_pool_slot_header_s *header =
pool->allocation + slot_index * slot_size;
header->next =
(void *) ((uint8_t *) pool->allocation
+ (slot_index + 1) * slot_size);
header->pool = pool;
++slot_index;
}
vx_pool_slot_header_s *last_header = (void *)
((uint8_t *) pool->allocation + slot_size * (pool->capacity - 1));
last_header->next = NULL;
}
vx_pool_s * vx_new_pool(uint32_t unit_size, uint32_t capacity)
{
uint32_t len_header = vx_ceil_to(sizeof(vx_pool_slot_header_s), 16);
uint32_t slot_size = vx_ceil_to(unit_size + len_header, 16);
vx_pool_s *pool = malloc(64 + (slot_size * capacity));
pool->allocation = (void *) vx_ceil_to((uint64_t) pool + 32, (uint64_t) 32);
pool->first_free = pool->allocation;
pool->unit_size = unit_size;
pool->capacity = capacity;
vx_reset_pool_allocation(pool, slot_size);
return pool;
}
void vx_free_pool(vx_pool_s *pool)
{
if(pool->continuation)
{
vx_free_pool(pool->continuation);
}
free(pool);
}
void * vx_pool(vx_pool_s *pool)
{
vx_pool_slot_header_s *item = pool->first_free;
if( ! item)
{
if( ! pool->continuation)
{
pool->continuation = vx_new_pool(pool->unit_size, pool->capacity * 2);
}
return vx_pool(pool->allocation);
}
pool->first_free = item->next;
return item + vx_ceil_to(sizeof(vx_pool_slot_header_s), 16);
}
void vx_unpool(void *allocation)
{
vx_pool_slot_header_s *slot_header =
allocation
- vx_ceil_to(sizeof(vx_pool_slot_header_s), 16);
slot_header->next = slot_header->pool->first_free;
slot_header->pool->first_free = slot_header;
}