mirror of https://github.com/flysand7/ciabatta.git
[bugfix] Make one freelist per pool, instead of one per buffer
This commit is contained in:
parent
344d9f0398
commit
8c0590e517
|
@ -48,14 +48,13 @@ struct Cia_Pool_Bucket {
|
|||
struct Cia_Pool_Buffer_Header typedef Cia_Pool_Buffer_Header;
|
||||
struct Cia_Pool_Buffer_Header {
|
||||
Cia_Pool_Buffer_Header *next;
|
||||
u64 free_buckets_count;
|
||||
Cia_Pool_Bucket *free_head;
|
||||
};
|
||||
|
||||
struct Cia_Pool typedef Cia_Pool;
|
||||
struct Cia_Pool {
|
||||
Cia_Allocator allocator;
|
||||
Cia_Pool_Buffer_Header *first;
|
||||
Cia_Pool_Bucket *freelist_head;
|
||||
u64 buffer_size;
|
||||
u64 bucket_size;
|
||||
u64 alignment;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
static void pool_reinit_buffer(Cia_Pool *pool, u8 *buffer) {
|
||||
static void *_pool_buffer_freelist_add(Cia_Pool *pool, u8 *buffer) {
|
||||
Cia_Pool_Buffer_Header *header = (Cia_Pool_Buffer_Header *)buffer;
|
||||
u64 header_size = sizeof(Cia_Pool_Buffer_Header);
|
||||
u64 header_size_aligned = cia_size_alignf(header_size, pool->alignment);
|
||||
|
@ -10,14 +10,15 @@ static void pool_reinit_buffer(Cia_Pool *pool, u8 *buffer) {
|
|||
u64 buckets_size = buckets_count * pool->bucket_size;
|
||||
// Initialize every bucket as free
|
||||
u64 bucket_offset = header_size_aligned + buckets_size;
|
||||
Cia_Pool_Bucket *next_bucket = NULL;
|
||||
Cia_Pool_Bucket *next_bucket = pool->freelist_head;
|
||||
do {
|
||||
bucket_offset -= pool->bucket_size;
|
||||
Cia_Pool_Bucket *bucket = (Cia_Pool_Bucket *)(buffer + bucket_offset);
|
||||
bucket->next = next_bucket;
|
||||
next_bucket = bucket;
|
||||
} while(bucket_offset > header_size_aligned);
|
||||
header->free_head = next_bucket;
|
||||
// Add the head of the newly-created freelist to the existing freelist
|
||||
pool->freelist_head = next_bucket;
|
||||
}
|
||||
|
||||
void cia_pool_create(Cia_Pool *pool, Cia_Allocator backing_allocator, u64 buffer_size, u64 bucket_size, u64 alignment) {
|
||||
|
@ -32,49 +33,28 @@ void cia_pool_create(Cia_Pool *pool, Cia_Allocator backing_allocator, u64 buffer
|
|||
// Make element size a multiple of the alignment
|
||||
pool->bucket_size = cia_size_alignf(pool->bucket_size, pool->alignment);
|
||||
// Allocate and initialize the first buffer
|
||||
pool->freelist_head = NULL;
|
||||
pool->first = allocator_alloc(&pool->allocator, pool->buffer_size, pool->alignment);
|
||||
pool_reinit_buffer(pool, (u8 *)pool->first);
|
||||
_pool_buffer_freelist_add(pool, (u8 *)pool->first);
|
||||
}
|
||||
|
||||
void *cia_pool_alloc(Cia_Pool *pool) {
|
||||
Cia_Pool_Buffer_Header *buffer = pool->first;
|
||||
// Find buffer with free data in it
|
||||
while(buffer != NULL) {
|
||||
if(buffer->free_buckets_count > 0) {
|
||||
break;
|
||||
}
|
||||
buffer = buffer->next;
|
||||
}
|
||||
// If none have it, then create a new buffer
|
||||
if(buffer == NULL) {
|
||||
void *buffer_mem = allocator_alloc(&pool->allocator, pool->buffer_size, pool->alignment);
|
||||
pool_reinit_buffer(pool, buffer_mem);
|
||||
Cia_Pool_Buffer_Header *header = buffer_mem;
|
||||
header->next = pool->first;
|
||||
pool->first = header;
|
||||
buffer = header;
|
||||
// If we don't have enough free buckets, create a new buffer
|
||||
if(pool->freelist_head == NULL) {
|
||||
void *buffer = allocator_alloc(&pool->allocator, pool->buffer_size, pool->alignment);
|
||||
_pool_buffer_freelist_add(pool, buffer);
|
||||
}
|
||||
// Remove item from free list and return it
|
||||
void *addr = buffer->free_head;
|
||||
buffer->free_head = buffer->free_head->next;
|
||||
void *addr = pool->freelist_head;
|
||||
pool->freelist_head = pool->freelist_head->next;
|
||||
return addr;
|
||||
}
|
||||
|
||||
void cia_pool_free(Cia_Pool *pool, void *ptr) {
|
||||
// Check which buffer the allocation is from
|
||||
Cia_Pool_Buffer_Header *source = NULL;
|
||||
for(Cia_Pool_Buffer_Header *buffer = pool->first; buffer != NULL; buffer = buffer->next) {
|
||||
void *buffer_start = buffer;
|
||||
void *buffer_end = (u8 *)buffer + pool->buffer_size;
|
||||
if(buffer_start < ptr && ptr < buffer_end) {
|
||||
source = buffer;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Add bucket to free list
|
||||
Cia_Pool_Bucket *bucket = ptr;
|
||||
bucket->next = source->free_head;
|
||||
source->free_head = bucket;
|
||||
bucket->next = pool->freelist_head;
|
||||
pool->freelist_head = bucket;
|
||||
}
|
||||
|
||||
void cia_pool_free_all(Cia_Pool *pool) {
|
||||
|
@ -83,7 +63,8 @@ void cia_pool_free_all(Cia_Pool *pool) {
|
|||
allocator_free_size(&pool->allocator, buffer, pool->buffer_size);
|
||||
}
|
||||
// Reinit the first buffer
|
||||
pool_reinit_buffer(pool, (u8 *)pool->first);
|
||||
pool->freelist_head = NULL;
|
||||
_pool_buffer_freelist_add(pool, (u8 *)pool->first);
|
||||
}
|
||||
|
||||
void cia_pool_destroy(Cia_Pool *pool) {
|
||||
|
|
Loading…
Reference in New Issue