#include "../include/scoped_allocator.h" #include "../include/alloc.h" #include #define ALLOC_NODE_SIZE 4096 int scoped_allocator_node_init(ScopedAllocatorNode *self) { self->data = NULL; self->size = 0; self->next = NULL; return am_malloc(ALLOC_NODE_SIZE, (void**)&self->data); } void scoped_allocator_node_deinit(ScopedAllocatorNode *self) { am_free(self->data); self->data = NULL; self->size = 0; if(self->next) { scoped_allocator_node_deinit(self->next); am_free(self->next); self->next = NULL; } } int scoped_allocator_init(ScopedAllocator *self) { return_if_error(scoped_allocator_node_init(&self->head)); self->current = &self->head; return buffer_init(&self->buffers, NULL); } static void buffer_deinit(Buffer *self) { am_free(self->data); self->data = NULL; self->size = 0; self->capacity = 0; } void scoped_allocator_deinit(ScopedAllocator *self) { Buffer *buffer; Buffer *buffer_end; scoped_allocator_node_deinit(&self->head); self->current = NULL; buffer = (Buffer*)&self->buffers.data[0]; buffer_end = buffer + self->buffers.size / sizeof(Buffer); while(buffer != buffer_end) { buffer_deinit(buffer); ++buffer; } buffer_deinit(&self->buffers); } static CHECK_RESULT int scoped_allocator_ensure_capacity_for(ScopedAllocator *self, usize size) { void *new_node; new_node = NULL; if(self->current->size + size > ALLOC_NODE_SIZE) { return_if_error(am_malloc(sizeof(ScopedAllocatorNode), &new_node)); cleanup_if_error(scoped_allocator_node_init(new_node)); self->current->next = new_node; self->current = new_node; } return 0; cleanup: if(new_node) am_free(new_node); return -1; } int scoped_allocator_alloc(ScopedAllocator *self, usize size, void **mem) { assert(self->current); assert(size <= ALLOC_NODE_SIZE); return_if_error(scoped_allocator_ensure_capacity_for(self, size)); *mem = &self->current->data[self->current->size]; self->current->size += size; return 0; } int scoped_allocator_add_buffer(ScopedAllocator *self, Buffer *buffer) { return buffer_append(&self->buffers, buffer, sizeof(buffer)); }