diff options
Diffstat (limited to 'src/kernel/mem')
-rw-r--r-- | src/kernel/mem/heap.c | 26 | ||||
-rw-r--r-- | src/kernel/mem/mem.c | 2 | ||||
-rw-r--r-- | src/kernel/mem/paging.c | 15 |
3 files changed, 27 insertions, 16 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; diff --git a/src/kernel/mem/mem.c b/src/kernel/mem/mem.c index 47a03dc..2061aff 100644 --- a/src/kernel/mem/mem.c +++ b/src/kernel/mem/mem.c @@ -7,7 +7,7 @@ #define FREEPAGESTOKEEP 5 #define KHEAP_IDXSIZE 0x1000 -#define KHEAP_INITSIZE 0x8000 +#define KHEAP_INITSIZE 0x80000 #define KHEAP_MAXSIZE 0x08000000 size_t mem_placementAddr; diff --git a/src/kernel/mem/paging.c b/src/kernel/mem/paging.c index f8f69f1..4e5f33a 100644 --- a/src/kernel/mem/paging.c +++ b/src/kernel/mem/paging.c @@ -134,13 +134,14 @@ uint32_t paging_fault(struct registers *regs) { } if (seg == 0) { - WHERE; monitor_write("Unhandled Page Fault "); - if (regs->err_code & 0x1) monitor_write("present "); - if (regs->err_code & 0x2) monitor_write("write "); - if (regs->err_code & 0x4) monitor_write("user "); - if (regs->err_code & 0x8) monitor_write("rsvd "); - if (regs->err_code & 0x10) monitor_write("instructionfetch "); - monitor_write("cr2:"); monitor_writeHex(addr); monitor_write("\n"); + NL; WHERE; monitor_write("Unhandled Page Fault\t"); + monitor_write("cr2:"); monitor_writeHex(addr); + NL; TAB; + if (regs->err_code & 0x1) monitor_write("present"); TAB; + if (regs->err_code & 0x2) monitor_write("write"); TAB; + if (regs->err_code & 0x4) monitor_write("user"); TAB; + if (regs->err_code & 0x8) monitor_write("rsvd"); TAB; + if (regs->err_code & 0x10) monitor_write("opfetch"); return 1; } return 0; |