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 typedef Cia_Pool_Buffer_Header;
|
||||||
struct Cia_Pool_Buffer_Header {
|
struct Cia_Pool_Buffer_Header {
|
||||||
Cia_Pool_Buffer_Header *next;
|
Cia_Pool_Buffer_Header *next;
|
||||||
u64 free_buckets_count;
|
|
||||||
Cia_Pool_Bucket *free_head;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Cia_Pool typedef Cia_Pool;
|
struct Cia_Pool typedef Cia_Pool;
|
||||||
struct Cia_Pool {
|
struct Cia_Pool {
|
||||||
Cia_Allocator allocator;
|
Cia_Allocator allocator;
|
||||||
Cia_Pool_Buffer_Header *first;
|
Cia_Pool_Buffer_Header *first;
|
||||||
|
Cia_Pool_Bucket *freelist_head;
|
||||||
u64 buffer_size;
|
u64 buffer_size;
|
||||||
u64 bucket_size;
|
u64 bucket_size;
|
||||||
u64 alignment;
|
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;
|
Cia_Pool_Buffer_Header *header = (Cia_Pool_Buffer_Header *)buffer;
|
||||||
u64 header_size = sizeof(Cia_Pool_Buffer_Header);
|
u64 header_size = sizeof(Cia_Pool_Buffer_Header);
|
||||||
u64 header_size_aligned = cia_size_alignf(header_size, pool->alignment);
|
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;
|
u64 buckets_size = buckets_count * pool->bucket_size;
|
||||||
// Initialize every bucket as free
|
// Initialize every bucket as free
|
||||||
u64 bucket_offset = header_size_aligned + buckets_size;
|
u64 bucket_offset = header_size_aligned + buckets_size;
|
||||||
Cia_Pool_Bucket *next_bucket = NULL;
|
Cia_Pool_Bucket *next_bucket = pool->freelist_head;
|
||||||
do {
|
do {
|
||||||
bucket_offset -= pool->bucket_size;
|
bucket_offset -= pool->bucket_size;
|
||||||
Cia_Pool_Bucket *bucket = (Cia_Pool_Bucket *)(buffer + bucket_offset);
|
Cia_Pool_Bucket *bucket = (Cia_Pool_Bucket *)(buffer + bucket_offset);
|
||||||
bucket->next = next_bucket;
|
bucket->next = next_bucket;
|
||||||
next_bucket = bucket;
|
next_bucket = bucket;
|
||||||
} while(bucket_offset > header_size_aligned);
|
} 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) {
|
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
|
// Make element size a multiple of the alignment
|
||||||
pool->bucket_size = cia_size_alignf(pool->bucket_size, pool->alignment);
|
pool->bucket_size = cia_size_alignf(pool->bucket_size, pool->alignment);
|
||||||
// Allocate and initialize the first buffer
|
// Allocate and initialize the first buffer
|
||||||
|
pool->freelist_head = NULL;
|
||||||
pool->first = allocator_alloc(&pool->allocator, pool->buffer_size, pool->alignment);
|
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) {
|
void *cia_pool_alloc(Cia_Pool *pool) {
|
||||||
Cia_Pool_Buffer_Header *buffer = pool->first;
|
// If we don't have enough free buckets, create a new buffer
|
||||||
// Find buffer with free data in it
|
if(pool->freelist_head == NULL) {
|
||||||
while(buffer != NULL) {
|
void *buffer = allocator_alloc(&pool->allocator, pool->buffer_size, pool->alignment);
|
||||||
if(buffer->free_buckets_count > 0) {
|
_pool_buffer_freelist_add(pool, buffer);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
// Remove item from free list and return it
|
// Remove item from free list and return it
|
||||||
void *addr = buffer->free_head;
|
void *addr = pool->freelist_head;
|
||||||
buffer->free_head = buffer->free_head->next;
|
pool->freelist_head = pool->freelist_head->next;
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cia_pool_free(Cia_Pool *pool, void *ptr) {
|
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
|
// Add bucket to free list
|
||||||
Cia_Pool_Bucket *bucket = ptr;
|
Cia_Pool_Bucket *bucket = ptr;
|
||||||
bucket->next = source->free_head;
|
bucket->next = pool->freelist_head;
|
||||||
source->free_head = bucket;
|
pool->freelist_head = bucket;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cia_pool_free_all(Cia_Pool *pool) {
|
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);
|
allocator_free_size(&pool->allocator, buffer, pool->buffer_size);
|
||||||
}
|
}
|
||||||
// Reinit the first buffer
|
// 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) {
|
void cia_pool_destroy(Cia_Pool *pool) {
|
||||||
|
|
Loading…
Reference in New Issue