summaryrefslogtreecommitdiff
path: root/src/kernel
diff options
context:
space:
mode:
authordzwdz2022-05-03 16:45:01 +0200
committerdzwdz2022-05-03 16:45:01 +0200
commitb6bce26e2b7ec3bd06d6f024ffa3efa165ca9b29 (patch)
tree39b0eabe60d16f29c455c0b2b9ce67fd9fd2e0b6 /src/kernel
parent8e276c64c9394d0964506bd6eaa7d4e0547d1ead (diff)
kernel/alloc: kfree() now actually frees memory
Diffstat (limited to 'src/kernel')
-rw-r--r--src/kernel/mem/alloc.c33
1 files changed, 22 insertions, 11 deletions
diff --git a/src/kernel/mem/alloc.c b/src/kernel/mem/alloc.c
index 44a46f9..64705ca 100644
--- a/src/kernel/mem/alloc.c
+++ b/src/kernel/mem/alloc.c
@@ -83,27 +83,38 @@ void page_free(void *first_addr, size_t pages) {
}
}
+struct malloc_hdr {
+ uint32_t magic;
+ uint32_t page_amt;
+};
void *kmalloc(size_t len) {
- void *addr;
- len += sizeof(uint32_t); // add space for MALLOC_MAGIC
- // extremely inefficient, but this is only temporary anyways
- addr = page_alloc(len / PAGE_SIZE + 1);
- *(uint32_t*)addr = MALLOC_MAGIC;
+ // TODO better kmalloc
+
+ struct malloc_hdr *addr;
+ uint32_t pages;
+
+ len += sizeof(struct malloc_hdr);
+ pages = len / PAGE_SIZE + 1;
+
+ addr = page_alloc(pages);
+ addr->magic = MALLOC_MAGIC;
+ addr->page_amt = pages;
malloc_balance++;
- return addr + sizeof(uint32_t);
+ return (void*)addr + sizeof(struct malloc_hdr);
}
void kfree(void *ptr) {
- uint32_t *magic = &((uint32_t*)ptr)[-1];
+ struct malloc_hdr *hdr;
if (ptr == NULL) return;
- if (*magic != MALLOC_MAGIC) {
- // TODO add some kind of separate system log
+
+ hdr = ptr - sizeof(struct malloc_hdr);
+ if (hdr->magic != MALLOC_MAGIC) {
kprintf("kfree() didn't find MALLOC_MAGIC @ 0x%x\n", ptr);
panic_invalid_state();
} else {
- // change the magic marker to detect double frees
- *magic = 0xBADF2EED;
+ hdr->magic = ~MALLOC_MAGIC; // (hopefully) detect double frees
+ page_free(hdr, hdr->page_amt);
}
malloc_balance--;
}