diff --git a/kernel/src/kmalloc.c b/kernel/src/kmalloc.c index fb67cb4..b59b730 100644 --- a/kernel/src/kmalloc.c +++ b/kernel/src/kmalloc.c @@ -1,8 +1,12 @@ +#include "errno.h" #include "kernel.h" +#include "paging.h" #include "types.h" +#include "vmm.h" #include #include #include +#include // this file contains SLUB inspired HEAP allocator // TODO this will be an allocated array later when we have APIC MADT @@ -55,7 +59,7 @@ void* kmalloc(size_t size) { size_t alloc_index; { uint8_t leading_zeros = __builtin_clzll(size); - if (/*__builtin_popcountll(size) == */1) { + if (popcountll(size) == 1) { alloc_index = leading_zeros; } else { alloc_index = sizeof(size) * CHAR_BIT - leading_zeros; @@ -125,6 +129,35 @@ void* kmalloc(size_t size) { } else { // slowest path + size_t object_size = (1 << (alloc_index+LOWEST_POWER)); + + uint8_t page_count = object_size < PAGE_SIZE ? 1 : (object_size*2)/PAGE_SIZE; + + void** alloc_addr = 0; + { + int ret; + ret = vmm_alloc((void**)&alloc_addr, page_count, 0); + if (ret != SUCCESS) { + return NULL; + } + } + + // construct the linked list + // start at offset if object too small for partial free list pointer + for (size_t i = object_size < sizeof(struct partialy_freelist) ? object_size : 0; i=page_count*PAGE_SIZE) { + alloc_addr[i*object_size] = NULL; + } else { + alloc_addr[i*object_size] = alloc_addr + ((i+1)*object_size); + } + } + if (object_size < sizeof(struct partialy_freelist)) { + freelists_all_cpus[core_id].freelists[alloc_index] = (struct freelist*)(alloc_addr+(object_size*2)); + return alloc_addr+object_size; + } else { + freelists_all_cpus[core_id].freelists[alloc_index] = (struct freelist*)(alloc_addr+object_size); + return alloc_addr; + } } } } \ No newline at end of file