summaryrefslogtreecommitdiff
path: root/src/kernel/mem
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel/mem')
-rw-r--r--src/kernel/mem/heap.c26
-rw-r--r--src/kernel/mem/mem.c2
-rw-r--r--src/kernel/mem/paging.c15
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;