mirror of https://github.com/flysand7/ciabatta.git
Add memory pool to cia-mem, use it for FILE
This commit is contained in:
parent
80fde89a6f
commit
d9f530fe58
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
void *cia_ptr_alignf(void *ptr, u64 alignment);
|
void *cia_ptr_alignf(void *ptr, u64 alignment);
|
||||||
void *cia_ptr_alignb(void *ptr, u64 alignment);
|
void *cia_ptr_alignb(void *ptr, u64 alignment);
|
||||||
|
u64 cia_size_alignf(u64 size, u64 alignment);
|
||||||
|
u64 cia_size_alignb(u64 size, u64 alignment);
|
||||||
|
|
||||||
#define CIA_MEM_OP_ALLOC 1
|
#define CIA_MEM_OP_ALLOC 1
|
||||||
#define CIA_MEM_OP_FREE 2
|
#define CIA_MEM_OP_FREE 2
|
||||||
|
@ -37,3 +39,31 @@ void *cia_arena_alloc(Cia_Arena *arena, u64 size);
|
||||||
void *cia_arena_alloc_aligned(Cia_Arena *arena, u64 size, u64 align);
|
void *cia_arena_alloc_aligned(Cia_Arena *arena, u64 size, u64 align);
|
||||||
void cia_arena_free_all(Cia_Arena *arena);
|
void cia_arena_free_all(Cia_Arena *arena);
|
||||||
void cia_arena_destroy(Cia_Arena *arena);
|
void cia_arena_destroy(Cia_Arena *arena);
|
||||||
|
|
||||||
|
struct Cia_Pool_Bucket typedef Cia_Pool_Bucket;
|
||||||
|
struct Cia_Pool_Bucket {
|
||||||
|
Cia_Pool_Bucket *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
|
u64 buffer_size;
|
||||||
|
u64 bucket_size;
|
||||||
|
u64 alignment;
|
||||||
|
};
|
||||||
|
|
||||||
|
void cia_pool_create(Cia_Pool *pool, Cia_Allocator backing_allocator, u64 buffer_size, u64 element_size, u64 alignment);
|
||||||
|
void *cia_pool_alloc(Cia_Pool *pool);
|
||||||
|
void cia_pool_free(Cia_Pool *pool, void *ptr);
|
||||||
|
void cia_pool_free_all(Cia_Pool *pool);
|
||||||
|
void cia_pool_destroy(Cia_Pool *pool);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,94 @@
|
||||||
|
|
||||||
|
static void pool_reinit_buffer(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);
|
||||||
|
u8 *buckets = buffer + header_size_aligned;
|
||||||
|
u64 remaining_size = pool->buffer_size - header_size_aligned;
|
||||||
|
u64 buckets_count = remaining_size / pool->bucket_size;
|
||||||
|
header->free_buckets_count = buckets_count;
|
||||||
|
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;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cia_pool_create(Cia_Pool *pool, Cia_Allocator backing_allocator, u64 buffer_size, u64 bucket_size, u64 alignment) {
|
||||||
|
pool->allocator = backing_allocator;
|
||||||
|
pool->buffer_size = buffer_size;
|
||||||
|
pool->bucket_size = bucket_size;
|
||||||
|
pool->alignment = alignment;
|
||||||
|
// If the unallocated element can't hold a bucket, increase the size of the element
|
||||||
|
if(pool->bucket_size < sizeof(Cia_Pool_Bucket)) {
|
||||||
|
pool->bucket_size = sizeof(Cia_Pool_Bucket);
|
||||||
|
}
|
||||||
|
// 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->first = allocator_alloc(&pool->allocator, pool->buffer_size, pool->alignment);
|
||||||
|
pool_reinit_buffer(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;
|
||||||
|
}
|
||||||
|
// Remove item from free list and return it
|
||||||
|
void *addr = buffer->free_head;
|
||||||
|
buffer->free_head = buffer->free_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;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cia_pool_free_all(Cia_Pool *pool) {
|
||||||
|
// Deallocate all buffers except the first one
|
||||||
|
for(Cia_Pool_Buffer_Header *buffer = pool->first->next; buffer != NULL; buffer = buffer->next) {
|
||||||
|
allocator_free_size(&pool->allocator, buffer, pool->buffer_size);
|
||||||
|
}
|
||||||
|
// Reinit the first buffer
|
||||||
|
pool_reinit_buffer(pool, (u8 *)pool->first);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cia_pool_destroy(Cia_Pool *pool) {
|
||||||
|
// Simply deallocate all the buffers
|
||||||
|
for(Cia_Pool_Buffer_Header *buffer = pool->first; buffer != NULL; buffer = buffer->next) {
|
||||||
|
allocator_free_size(&pool->allocator, buffer, pool->buffer_size);
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,4 +9,12 @@ void *cia_ptr_alignb(void *ptr, u64 alignment) {
|
||||||
u64 addr = (u64)ptr;
|
u64 addr = (u64)ptr;
|
||||||
u64 aligned = addr & ~(alignment - 1);
|
u64 aligned = addr & ~(alignment - 1);
|
||||||
return (void *)aligned;
|
return (void *)aligned;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 cia_size_alignf(u64 size, u64 alignment) {
|
||||||
|
return (size + alignment - 1) & ~(alignment - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 cia_size_alignb(u64 size, u64 alignment) {
|
||||||
|
return size & ~(alignment - 1);
|
||||||
}
|
}
|
|
@ -3,17 +3,17 @@ FILE *stdin;
|
||||||
FILE *stdout;
|
FILE *stdout;
|
||||||
FILE *stderr;
|
FILE *stderr;
|
||||||
|
|
||||||
// TODO: memory allocation
|
static Cia_Pool _page_allocator;
|
||||||
static FILE _files[64];
|
static Cia_Pool _file_pool;
|
||||||
static int _files_cnt = 0;
|
|
||||||
|
|
||||||
static void _fileapi_init() {
|
static void _fileapi_init() {
|
||||||
|
cia_pool_create(&_file_pool, cia_allocator_pages(), 0x1000, sizeof(FILE), 16);
|
||||||
|
FILE *stdin = cia_pool_alloc(&_file_pool);
|
||||||
|
FILE *stdout = cia_pool_alloc(&_file_pool);
|
||||||
|
FILE *stderr = cia_pool_alloc(&_file_pool);
|
||||||
_rt_file_std_handles_init();
|
_rt_file_std_handles_init();
|
||||||
stdin = &_files[_files_cnt++];
|
|
||||||
stdin->rt_file = _rt_file_stdin;
|
stdin->rt_file = _rt_file_stdin;
|
||||||
stdout = &_files[_files_cnt++];
|
|
||||||
stdout->rt_file = _rt_file_stdout;
|
stdout->rt_file = _rt_file_stdout;
|
||||||
stderr = &_files[_files_cnt++];
|
|
||||||
stderr->rt_file = _rt_file_stderr;
|
stderr->rt_file = _rt_file_stderr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,8 +30,7 @@ FILE *fopen(char const *restrict filename, char const *restrict mode) {
|
||||||
if(status != _RT_STATUS_OK) {
|
if(status != _RT_STATUS_OK) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
FILE *file = &_files[_files_cnt];
|
FILE *file = cia_pool_alloc(&_file_pool);
|
||||||
_files_cnt += 1;
|
|
||||||
file->rt_file = rt_file;
|
file->rt_file = rt_file;
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,6 +61,7 @@ apis: [
|
||||||
"util.c",
|
"util.c",
|
||||||
"allocator.c",
|
"allocator.c",
|
||||||
"arena.c",
|
"arena.c",
|
||||||
|
"pool.c",
|
||||||
],
|
],
|
||||||
reqs: [
|
reqs: [
|
||||||
"rt_api_memory"
|
"rt_api_memory"
|
||||||
|
@ -84,7 +85,8 @@ apis: [
|
||||||
"file.c"
|
"file.c"
|
||||||
],
|
],
|
||||||
reqs: [
|
reqs: [
|
||||||
"rt_api_file"
|
"rt_api_file",
|
||||||
|
"cia_memory",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
Loading…
Reference in New Issue