Base/platform/src-c/alloc/pool.c

89 lines
2.9 KiB
C

#include <librr/alloc/generic.h>
#include <librr/memory.h>
#include <alloc/pool.h>
void rr_initialize_pool_allocation(rr_pool_s *pool)
{
usz_t slot_size = sizeof(rr_pool_unit_header_s) + pool->item_size;
slot_size = (slot_size + (32 - slot_size % 32));
usz_t slot_index = 0;
while(slot_index < pool->capacity)
{
rr_pool_unit_header_s *current_header = pool->allocation + (slot_index * slot_size);
current_header->next = current_header + slot_size;
++slot_index;
}
rr_pool_unit_header_s *last_header = pool->allocation + ((pool->capacity - 1) * slot_size);
last_header->next = NULL;
}
rr_generic_pool_s rr_new_dynamic_pool(rr_generic_allocator_s *allocator, usz_t item_size, usz_t capacity)
{
// Size of (header + item) rounded up to 32
usz_t slot_size = sizeof(rr_pool_unit_header_s) + item_size;
slot_size = (slot_size + (32 - slot_size % 32));
rr_pool_s pool;
pool.allocator = allocator;
pool.allocation = rr_alloc(allocator, slot_size * capacity);
pool.item_size = item_size;
pool.capacity = capacity;
pool.first_free = pool.allocation;
rr_initialize_pool_allocation(&pool);
rr_generic_pool_s generic_pool;
generic_pool.fn_alloc = &rr_pool_alloc_slot;
generic_pool.fn_free = &rr_pool_free_slot;
generic_pool.fn_destruct = &rr_destruct_pool;
return generic_pool;
}
rr_generic_pool_s rr_new_static_pool(rr_generic_allocator_s *allocator, usz_t item_size, usz_t capacity)
{
// Size of (header + item) rounded up to 32
usz_t slot_size = sizeof(rr_pool_unit_header_s) + item_size;
slot_size = (slot_size + (32 - slot_size % 32));
rr_pool_s pool;
pool.allocator = allocator;
pool.allocation = rr_alloc(allocator, slot_size * capacity);
pool.item_size = item_size;
pool.capacity = capacity;
pool.first_free = pool.allocation;
rr_initialize_pool_allocation(&pool);
rr_generic_pool_s generic_pool;
generic_pool.fn_alloc = &rr_pool_alloc_slot;
generic_pool.fn_free = &rr_pool_free_slot;
generic_pool.fn_destruct = &rr_destruct_pool;
return generic_pool;
}
void rr_destruct_pool(rr_generic_pool_s *generic_pool)
{
rr_pool_s *specifics = generic_pool->specifics;
rr_free(specifics->allocator, specifics->allocation);
rr_free(specifics->allocator, specifics);
}
void * rr_pool_alloc_slot(rr_generic_pool_s *generic_pool)
{
rr_pool_s *specifics = generic_pool->specifics;
rr_pool_unit_header_s *header = specifics->first_free;
specifics->first_free = header->next;
void *item = header + sizeof(rr_pool_unit_header_s);
rr_memset(item, specifics->item_size, 0x00);
return item;
}
void rr_pool_free_slot(rr_generic_pool_s *generic_pool, void *block)
{
rr_pool_s *specifics = generic_pool->specifics;
rr_pool_unit_header_s *header = block - sizeof(rr_pool_unit_header_s);
header->next = specifics->first_free;
specifics->first_free = header;
}