diff --git a/kernel/GNUmakefile b/kernel/GNUmakefile index e25cc41..de5ae61 100644 --- a/kernel/GNUmakefile +++ b/kernel/GNUmakefile @@ -51,12 +51,13 @@ else endif CPPFLAGS := -I../external -I$(SRCDIR) -MMD -MP -DLIMINE_API_REVISION=3 -CFLAGS += -std=c99 +CFLAGS += -std=c99 IMPLICIT_SRCS := ifneq ($(MAKECMDGOALS),menuconfig) ifeq ($(CONFIG_KERNEL_HEAP_FF),y) IMPLICIT_SRCS += src/mm/heap/ff.c + CFLAGS += -DFF_POOL_SIZE=$(CONFIG_KERNEL_HEAP_POOL_SIZE) else $(error Error: No heap algorithm was defined. Please run "make menuconfig" and select one.) endif diff --git a/kernel/Kconfig b/kernel/Kconfig index 61569c8..e29327e 100644 --- a/kernel/Kconfig +++ b/kernel/Kconfig @@ -1,39 +1,54 @@ mainmenu "EMK Build Configuration" -choice - prompt "Build Mode" - default BUILD_MODE_DEBUG +menu "Build" + choice + prompt "Build Mode" + default BUILD_MODE_DEBUG -config BUILD_MODE_DEBUG - bool "Debug" - help - Build with debug symbols and no optimizations. + config BUILD_MODE_DEBUG + bool "Debug" + help + Build with debug symbols and no optimizations. -config BUILD_MODE_RELEASE - bool "Release" - help - Build with optimizations and no debug symbols. + config BUILD_MODE_RELEASE + bool "Release" + help + Build with optimizations and no debug symbols. -endchoice + endchoice +endmenu -choice - prompt "Kernel Heap Algorithm" - default KERNEL_HEAP_FF +menu "Memory" + choice + prompt "Kernel Heap Algorithm" + default KERNEL_HEAP_FF -config KERNEL_HEAP_FF - bool "First-Fit" - help - Use the First-Fit memory allocation algorithm (ff.c). + config KERNEL_HEAP_FF + bool "First-Fit" + help + Use the First-Fit memory allocation algorithm (ff.c). -endchoice + endchoice -config ENABLE_FLANTERM - bool "Enable Flanterm Support" - help - Includes support for the Flanterm terminal emulator. Useful for debugging real hardware. + config KERNEL_HEAP_POOL_SIZE + int "Pool Size (Pages)" + default 512 + depends on KERNEL_HEAP_FF + help + Set the pool size in pages for the First-Fit heap algorithm. +endmenu -config CC - string "C Compiler" - default "gcc" - help - Path to the C compiler to use for building. +menu "Toolchain" + config CC + string "C Compiler" + default "gcc" + help + Path to the C compiler to use for building. +endmenu + +menu "Extras" + config ENABLE_FLANTERM + bool "Enable Flanterm Support" + help + Includes support for the Flanterm terminal emulator. Useful for debugging real hardware. +endmenu diff --git a/kernel/src/mm/heap/ff.c b/kernel/src/mm/heap/ff.c index 85386c0..1955df6 100644 --- a/kernel/src/mm/heap/ff.c +++ b/kernel/src/mm/heap/ff.c @@ -6,6 +6,7 @@ #include #include #include +#include void *pool; block_t *freelist = NULL; @@ -18,6 +19,7 @@ void heap_init() freelist = (block_t *)pool; freelist->size = (FF_POOL_SIZE * PAGE_SIZE) - sizeof(block_t); freelist->next = NULL; + log_early("Initialized heap with a pool of %d pages (~%dMB)", FF_POOL_SIZE, DIV_ROUND_UP(FF_POOL_SIZE * PAGE_SIZE, 1024 * 1024)); } void *kmalloc(size_t size) @@ -73,10 +75,35 @@ void kfree(void *ptr) if (!ptr) return; - /* get block header */ block_t *block = (block_t *)((uint8_t *)ptr - sizeof(block_t)); - /* insert freed block at head of freelist */ - block->next = freelist; - freelist = block; -} \ No newline at end of file + /* insert block sorted by address in freelist */ + block_t **cur = &freelist; + while (*cur && *cur < block) + { + cur = &(*cur)->next; + } + + block->next = *cur; + *cur = block; + + /* coalesce with next block if adjacent */ + if (block->next && (uint8_t *)block + sizeof(block_t) + block->size == (uint8_t *)block->next) + { + block->size += sizeof(block_t) + block->next->size; + block->next = block->next->next; + } + + /* coalesce with previous block if adjacent */ + if (cur != &freelist) + { + block_t *prev = freelist; + while (prev->next != block) + prev = prev->next; + if ((uint8_t *)prev + sizeof(block_t) + prev->size == (uint8_t *)block) + { + prev->size += sizeof(block_t) + block->size; + prev->next = block->next; + } + } +} diff --git a/kernel/src/mm/heap/ff.h b/kernel/src/mm/heap/ff.h index 9ed39c1..92b355c 100644 --- a/kernel/src/mm/heap/ff.h +++ b/kernel/src/mm/heap/ff.h @@ -7,7 +7,9 @@ #include #include -#define FF_POOL_SIZE 512 // 2MB, in pages +#ifndef FF_POOL_SIZE +#define FF_POOL_SIZE 512 +#endif // FF_POOL_SIZE typedef struct block {