From aba6ed4b91aff5d914be11704e34de75bfd4d003 Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Fri, 10 Sep 2010 18:46:00 +0200 Subject: Each thread has its own stack. Added simple unit tests for kmalloc,kfree Found a bug in heap_contract (not sure) but didn't fix it. --- src/kernel/mem/heap.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) (limited to 'src/kernel/mem/heap.c') diff --git a/src/kernel/mem/heap.c b/src/kernel/mem/heap.c index b7f6c97..79ef81e 100644 --- a/src/kernel/mem/heap.c +++ b/src/kernel/mem/heap.c @@ -1,5 +1,8 @@ #include "heap.h" #include "paging.h" +#include + +#include #define HEAP_MAGIC 0xBAD0BEEF #define HEAP_MIN_SIZE 0x4000 @@ -11,7 +14,7 @@ static void heapIdx_insert(struct heap *heap, struct heap_header *e) { if ((heap->idxused + sizeof(struct heap_header*) + (size_t)heap->idx) >= heap->start_addr) return; uint32_t iterator = 0, pos; - while (iterator < heap->idxused && heap->idx[iterator]->size < e->size) { + while (iterator < heap->idxused && heap->idx[iterator]->size <= e->size) { if (heap->idx[iterator] == e) return; iterator++; } @@ -122,15 +125,19 @@ static uint32_t heap_expand(struct heap *heap, size_t quantity) { /* For internal use only. Called by heap_free when necessary. Reduces the heap's size. */ static void heap_contract(struct heap *heap) { + return; //TODO: this function bugs everything + + struct heap_footer *last_footer = (struct heap_footer*)(heap->end_addr - sizeof(struct heap_footer)); struct heap_header *last_header = last_footer->header; if (last_header->is_hole == 0) return; + if (last_header->size <= 0x1000) return; - size_t quantity = 0; - while ((heap->end_addr - heap->start_addr) - quantity > HEAP_MIN_SIZE && - (last_header->size - quantity) > 0x1000) - quantity += 0x1000; + size_t quantity = ((heap->end_addr - heap->start_addr) & 0xFFFFF000) - 0x1000; + while ((heap->end_addr - heap->start_addr) - quantity < HEAP_MIN_SIZE || + last_header->size - 0x4000 < quantity) + quantity -= 0x1000; if (quantity == 0) return; size_t newEnd = heap->end_addr - quantity; @@ -149,6 +156,7 @@ static void heap_contract(struct heap *heap) { /* Alocate some bytes on the heap. */ void* heap_alloc(struct heap *heap, size_t sz) { + ASSERT(heap > 0xE0000000); size_t newsize = sz + sizeof(struct heap_header) + sizeof(struct heap_footer); uint32_t iterator = 0; @@ -158,17 +166,19 @@ void* heap_alloc(struct heap *heap, size_t sz) { } if (iterator == heap->idxused) { //No hole is big enough - if (heap_expand(heap, (sz & 0xFFFFF000) + 0x1000) == 0) return 0; //FAILED + if (heap_expand(heap, + MAX((heap->end_addr - heap->start_addr) & 0xFFFFF000, (newsize & 0xFFFFF000) + 0x1000) + ) == 0) return 0; //FAILED return heap_alloc(heap, sz); } struct heap_header *loc = heap->idx[iterator]; + heapIdx_remove(heap, loc); struct heap_footer *footer = (struct heap_footer*)((size_t)loc + loc->size - sizeof(struct heap_footer)); loc->is_hole = 0; - heapIdx_remove(heap, loc); //If we have enough space to create a USEFUL new hole next to the allocated block, do it. - //If we do not, we might return a block that is a few bytes bigger than neede. + //If we do not, we might return a block that is a few bytes bigger than needed. if (loc->size > (newsize + sizeof(struct heap_header) + sizeof(struct heap_footer))) { loc->size = newsize; -- cgit v1.2.3