From 7fad0f984f9af1f10acb129c1cd88249a0855675 Mon Sep 17 00:00:00 2001 From: Abdelrahman Said Date: Thu, 18 May 2023 00:27:31 +0100 Subject: [PATCH] Defined the allocate function --- allocator.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 79 insertions(+), 4 deletions(-) diff --git a/allocator.c b/allocator.c index 57990ff..1be5b53 100644 --- a/allocator.c +++ b/allocator.c @@ -96,7 +96,82 @@ void deinit_allocator(allocator_t **allocator) { } } -// void *alloc(allocator_t *allocator, u64 size) { -// ++size; -// return NULL; -// } +void *allocate(allocator_t *allocator, u64 size) { + u64 min_size_required = size + sizeof(block_header) + sizeof(block_footer); + + if (!allocator || allocator->used == allocator->size || + min_size_required > allocator->size - allocator->used) { + return NULL; + } + + block_header *header = NULL; + + u64 block_index = 0; + + for (u64 i = 0; i < allocator->free_count; ++i) { + block_header *current = allocator->free_blocks[i]; + + if (current->size == min_size_required) { + header = current; + block_index = i; + break; + } + + if (!header || (header && current->size < header->size && + current->size > min_size_required)) { + header = current; + block_index = i; + } + } + + if (header) { + u8 *header_start = (u8 *)header; + + block_footer *footer = + (block_footer *)(header_start + header->size - sizeof(block_footer)); + + u64 old_size = header->size; + + bool create_new_block = false; + + // If allocating exactly the required size will leave enough memory to + // create another block, set the header size to min_size_required + if (old_size - min_size_required > + sizeof(block_header) + sizeof(block_footer)) { + header->size = min_size_required; + + create_new_block = true; + } + + header->free = false; + + if (create_new_block) { + footer->size -= header->size; + + block_header *new_header = (block_header *)(header_start + header->size); + new_header->size = old_size - header->size; + new_header->magic_01 = header->magic_01; + new_header->magic_02 = header->magic_02; + new_header->free = true; + + allocator->free_blocks[block_index] = new_header; + + block_footer *new_footer = + (block_footer *)(header_start + header->size - sizeof(block_footer)); + new_footer->size = header->size - sizeof(block_footer); + new_footer->magic_01 = footer->magic_01; + new_footer->magic_02 = footer->magic_02; + new_footer->free = false; + } else { + footer->free = false; + + --(allocator->free_count); + } + + allocator->used += header->size; + + return (void *)(header_start + sizeof(block_header)); + } + + return NULL; +}