diff options
author | Alexis211 <alexis211@gmail.com> | 2010-09-10 18:46:00 +0200 |
---|---|---|
committer | Alexis211 <alexis211@gmail.com> | 2010-09-10 18:46:00 +0200 |
commit | aba6ed4b91aff5d914be11704e34de75bfd4d003 (patch) | |
tree | 3d5cf90e9ccad09d352c6a61e90027ef552dd87f /src/kernel/mem/heap.c | |
parent | 5fc3baaa17a6ffb34490bb8accb86f53ef3d6d15 (diff) | |
download | TCE-aba6ed4b91aff5d914be11704e34de75bfd4d003.tar.gz TCE-aba6ed4b91aff5d914be11704e34de75bfd4d003.zip |
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.
Diffstat (limited to 'src/kernel/mem/heap.c')
-rw-r--r-- | src/kernel/mem/heap.c | 26 |
1 files changed, 18 insertions, 8 deletions
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 <core/sys.h> + +#include <lib/stdlib.h> #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; |