89 lines
2.9 KiB
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;
|
||
|
}
|