From 72f55421fb61b750512f324d284b30e3e67e36e0 Mon Sep 17 00:00:00 2001 From: dzwdz Date: Wed, 13 Mar 2024 22:33:38 +0100 Subject: kernel/malloc: slight rework (it's still bad), store more metadata --- src/kernel/malloc.c | 142 +++++++++++++++++++++++++++++++++++----------------- 1 file changed, 95 insertions(+), 47 deletions(-) (limited to 'src/kernel/malloc.c') diff --git a/src/kernel/malloc.c b/src/kernel/malloc.c index 7efd5a5..8ba00dc 100644 --- a/src/kernel/malloc.c +++ b/src/kernel/malloc.c @@ -6,23 +6,28 @@ #include #include -#define MALLOC_MAGIC 0xA770C666 - -struct malloc_hdr { - uint32_t magic; - uint32_t page_amt; - struct malloc_hdr *next, *prev; +#define MALLOC_MAGIC 0x616c6c6f63686472 +#define DESCLEN 8 + +typedef struct Allocation Allocation; +struct Allocation { + uint64_t magic; + uint64_t len; + Allocation *next, *prev; void *stacktrace[4]; + char desc[DESCLEN]; }; -struct malloc_hdr *malloc_last = NULL; +Allocation *malloc_last = NULL; extern uint8_t pbitmap[]; /* linker.ld */ static size_t pbitmap_len; /* in bytes */ static size_t pbitmap_firstfree = 0; -static bool bitmap_get(long i) { +static +bool bitmap_get(long i) +{ assert(i >= 0); size_t b = i / 8; uint8_t m = 1 << (i&7); @@ -30,7 +35,9 @@ static bool bitmap_get(long i) { return (pbitmap[b]&m) != 0; } -static bool bitmap_set(long i, bool v) { +static +bool bitmap_set(long i, bool v) +{ assert(i >= 0); size_t b = i / 8; uint8_t m = 1 << (i&7); @@ -41,18 +48,30 @@ static bool bitmap_set(long i, bool v) { return prev; } -static long toindex(void *p) { +static +long toindex(void *p) +{ return ((long)p - (long)pbitmap) / PAGE_SIZE; } -void mem_init(void *memtop) { +static +size_t page_amt(size_t bytes) +{ + return (bytes + PAGE_SIZE - 1) / PAGE_SIZE; +} + +void +mem_init(void *memtop) +{ kprintf("memory %8x -> %8x\n", &_bss_end, memtop); pbitmap_len = toindex(memtop) / 8; memset(pbitmap, 0, pbitmap_len); mem_reserve(pbitmap, pbitmap_len); } -void mem_reserve(void *addr, size_t len) { +void +mem_reserve(void *addr, size_t len) +{ kprintf("reserved %8x -> %8x\n", addr, addr + len); /* align to the previous page */ @@ -67,21 +86,36 @@ void mem_reserve(void *addr, size_t len) { } } -void mem_debugprint(void) { - size_t total = 0; - kprintf("current kmallocs:\n"); - kprintf("addr pages\n"); - for (struct malloc_hdr *iter = malloc_last; iter; iter = iter->prev) { - kprintf("%08x %05x", iter, iter->page_amt); - for (size_t i = 0; i < 4; i++) - kprintf(" k/%08x", iter->stacktrace[i]); - kprintf("\n peek 0x%x\n", *(uint32_t*)(&iter[1])); - total++; +void +mem_debugprint(void) +{ + size_t count = 0, bytes = 0, pages = 0; + kprintf("[kern] current allocations:\n"); + for (Allocation *iter = malloc_last; iter; iter = iter->prev) { + kprintf( + "%08p %6dB %.8s ", + ((void*)iter) + sizeof(Allocation), + iter->len - sizeof(Allocation), + iter->desc + ); + for (size_t i = 0; i < 4; i++) { + kprintf(" k/%08x", iter->stacktrace[i]); + } + kprintf("\n"); + + count++; + bytes += iter->len; + pages += page_amt(iter->len); } - kprintf(" total 0x%x\n", total); + kprintf( + "%d in total, %d bytes, %d pages = %dB used\n", + count, bytes, pages, pages*PAGE_SIZE + ); } -void *page_alloc(size_t pages) { +void +*page_alloc(size_t pages) +{ /* i do realize how painfully slow this is */ size_t streak = 0; for (size_t i = pbitmap_firstfree; i < pbitmap_len * 8; i++) { @@ -102,14 +136,18 @@ void *page_alloc(size_t pages) { panic_unimplemented(); } -void *page_zalloc(size_t pages) { +void +*page_zalloc(size_t pages) +{ void *p = page_alloc(pages); memset(p, 0, pages * PAGE_SIZE); return p; } -// frees `pages` consecutive pages starting from *first -void page_free(void *addr, size_t pages) { +/* frees `pages` consecutive pages starting from *first */ +void +page_free(void *addr, size_t pages) +{ assert(addr >= (void*)pbitmap); size_t first = toindex(addr); for (size_t i = 0; i < pages; i++) { @@ -122,27 +160,35 @@ void page_free(void *addr, size_t pages) { } } -void kmalloc_sanity(const void *addr) { +void +kmalloc_sanity(const void *addr) +{ assert(addr); - const struct malloc_hdr *hdr = addr - sizeof(struct malloc_hdr); + const Allocation *hdr = addr - sizeof(Allocation); assert(hdr->magic == MALLOC_MAGIC); if (hdr->next) assert(hdr->next->prev == hdr); if (hdr->prev) assert(hdr->prev->next == hdr); } -void *kmalloc(size_t len) { - // TODO better kmalloc - - struct malloc_hdr *hdr; +// TODO better kmalloc +void +*kmalloc(size_t len, const char *desc) +{ + Allocation *hdr; void *addr; - uint32_t pages; - - len += sizeof(struct malloc_hdr); - pages = len / PAGE_SIZE + 1; - hdr = page_alloc(pages); + len += sizeof(Allocation); + hdr = page_alloc(page_amt(len)); hdr->magic = MALLOC_MAGIC; - hdr->page_amt = pages; + hdr->len = len; + + memset(hdr->desc, ' ', DESCLEN); + if (desc) { + for (int i = 0; i < DESCLEN; i++) { + if (desc[i] == '\0') break; + hdr->desc[i] = desc[i]; + } + } hdr->next = NULL; hdr->prev = malloc_last; @@ -156,7 +202,7 @@ void *kmalloc(size_t len) { malloc_last = hdr; - addr = (void*)hdr + sizeof(struct malloc_hdr); + addr = (void*)hdr + sizeof(Allocation); #ifndef NDEBUG memset(addr, 0xCC, len); #endif @@ -164,13 +210,16 @@ void *kmalloc(size_t len) { return addr; } -void kfree(void *ptr) { - struct malloc_hdr *hdr; - uint32_t page_amt; +void +kfree(void *ptr) +{ + Allocation *hdr; + size_t pages; if (ptr == NULL) return; - hdr = ptr - sizeof(struct malloc_hdr); + hdr = ptr - sizeof(Allocation); kmalloc_sanity(ptr); + pages = page_amt(hdr->len); hdr->magic = ~MALLOC_MAGIC; // (hopefully) detect double frees if (hdr->next) @@ -179,9 +228,8 @@ void kfree(void *ptr) { hdr->prev->next = hdr->next; if (malloc_last == hdr) malloc_last = hdr->prev; - page_amt = hdr->page_amt; #ifndef NDEBUG - memset(hdr, 0xC0, page_amt * PAGE_SIZE); + memset(hdr, 0xC0, pages * PAGE_SIZE); #endif - page_free(hdr, page_amt); + page_free(hdr, pages); } -- cgit v1.2.3