diff options
author | dzwdz | 2024-07-14 16:39:43 +0200 |
---|---|---|
committer | dzwdz | 2024-07-14 16:39:43 +0200 |
commit | 8e403358b5a7ec3a5933257a95aa528c7f503ba0 (patch) | |
tree | b60a0a132c340a5f56a83c8667417fb268b4a80a /src | |
parent | c1d3ac750b8483c9a942d2fb5d5b7245d014e905 (diff) |
kernel/malloc: clean up the code a little bit
The bitmap functions now accept page addresses so I don't have to handle
raw bitmap indexes, which was kinda complex.
kmalloc_sanity is now not visible to other code as it wasn't really that useful
in the first place.
Diffstat (limited to 'src')
-rw-r--r-- | src/kernel/malloc.c | 107 | ||||
-rw-r--r-- | src/kernel/malloc.h | 1 | ||||
-rw-r--r-- | src/kernel/syscalls.c | 2 |
3 files changed, 47 insertions, 63 deletions
diff --git a/src/kernel/malloc.c b/src/kernel/malloc.c index ba1ab42..471c945 100644 --- a/src/kernel/malloc.c +++ b/src/kernel/malloc.c @@ -6,7 +6,7 @@ #include <stdbool.h> #include <stdint.h> -#define MALLOC_MAGIC 0x616c6c6f63686472 +#define MALLOC_MAGIC 0x616c6c6f63686472 /* "allochdr" */ #define DESCLEN 8 typedef struct Allocation Allocation; @@ -18,55 +18,61 @@ struct Allocation { char desc[DESCLEN]; }; -Allocation *malloc_last = NULL; +static Allocation *malloc_last = NULL; extern uint8_t pbitmap[]; /* linker.ld */ static size_t pbitmap_len; /* in bytes */ -static size_t pbitmap_firstfree = 0; +static void *firstfreepage; /* not necessarily actually free */ +static void *memtop; +static size_t +toindex(void *p) +{ + assert((void*)pbitmap <= p); + return ((uintptr_t)p - (uintptr_t)pbitmap) / PAGE_SIZE; +} -static -bool bitmap_get(long i) +static bool +pbitmap_get(void *p) { - assert(i >= 0); + size_t i = toindex(p); size_t b = i / 8; uint8_t m = 1 << (i&7); - assert(b < pbitmap_len); + assert(b < pbitmap_len); // TODO the bitmap should be a tad longer return (pbitmap[b]&m) != 0; } -static -bool bitmap_set(long i, bool v) +static bool +pbitmap_set(void *p, bool v) { - assert(i >= 0); + size_t i = toindex(p); size_t b = i / 8; uint8_t m = 1 << (i&7); assert(b < pbitmap_len); bool prev = (pbitmap[b]&m) != 0; - if (v) pbitmap[b] |= m; - else pbitmap[b] &= ~m; + if (v) { + pbitmap[b] |= m; + } else { + pbitmap[b] &= ~m; + } return prev; } -static -long toindex(void *p) -{ - return ((long)p - (long)pbitmap) / PAGE_SIZE; -} - -static -size_t page_amt(size_t bytes) +static size_t +page_amt(size_t bytes) { return (bytes + PAGE_SIZE - 1) / PAGE_SIZE; } void -mem_init(void *memtop) +mem_init(void *p) { + memtop = p; kprintf("memory %8x -> %8x\n", &_bss_end, memtop); pbitmap_len = toindex(memtop) / 8; memset(pbitmap, 0, pbitmap_len); mem_reserve(pbitmap, pbitmap_len); + firstfreepage = pbitmap; } void @@ -74,16 +80,12 @@ mem_reserve(void *addr, size_t len) { kprintf("reserved %8x -> %8x\n", addr, addr + len); - /* align to the previous page */ - size_t off = (uintptr_t)addr & PAGE_MASK; - addr -= off; - len += off; - size_t first = toindex(addr); - for (size_t i = 0; i * PAGE_SIZE < len; i++) { - if ((first + i) / 8 >= pbitmap_len) - break; - bitmap_set(first + i, true); + void *top = min(addr + len, memtop); + addr = (void*)((uintptr_t)addr & ~PAGE_MASK); /* round down to page */ + for (void *p = max(addr, (void*)pbitmap); p < top; p += PAGE_SIZE) { + pbitmap_set(p, true); } + } void @@ -113,55 +115,41 @@ mem_debugprint(void) ); } -void -*page_alloc(size_t pages) +void * +page_alloc(size_t pages) { - assert(pages == 1); /* not using that assertion... yet */ - /* i do realize how painfully slow this is */ - size_t streak = 0; - for (size_t i = pbitmap_firstfree; i < pbitmap_len * 8; i++) { - if (bitmap_get(i)) { - streak = 0; - continue; - } - if (++streak >= pages) { - /* found hole big enough for this allocation */ - i = i + 1 - streak; - for (size_t j = 0; j < streak; j++) - bitmap_set(i + j, true); - pbitmap_firstfree = i + streak - 1; - return pbitmap + i * PAGE_SIZE; + assert(pages == 1); + for (void *p = firstfreepage; p < memtop; p += PAGE_SIZE) { + if (!pbitmap_get(p)) { + pbitmap_set(p, true); + firstfreepage = p + PAGE_SIZE; + return p; } } kprintf("we ran out of memory :(\ngoodbye.\n"); 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) { - assert(addr >= (void*)pbitmap); - size_t first = toindex(addr); + assert((void*)pbitmap <= addr); for (size_t i = 0; i < pages; i++) { - if (bitmap_set(first + i, false) == false) { + if (pbitmap_set(addr + i*PAGE_SIZE, false) == false) { panic_invalid_state(); } } - if (pbitmap_firstfree > first) { - pbitmap_firstfree = first; - } } -void +static void kmalloc_sanity(const void *addr) { assert(addr); @@ -171,9 +159,8 @@ kmalloc_sanity(const void *addr) if (hdr->prev) assert(hdr->prev->next == hdr); } -// TODO better kmalloc -void -*kmalloc(size_t len, const char *desc) +void * +kmalloc(size_t len, const char *desc) { Allocation *hdr; void *addr; diff --git a/src/kernel/malloc.h b/src/kernel/malloc.h index 3469f5f..efbd9c8 100644 --- a/src/kernel/malloc.h +++ b/src/kernel/malloc.h @@ -20,7 +20,6 @@ void *page_zalloc(size_t pages); // frees `pages` consecutive pages starting from *first void page_free(void *first, size_t pages); -void kmalloc_sanity(const void *addr); void *kmalloc(size_t len, const char *desc); void kfree(void *ptr); diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c index 7fcbd2a..39115e7 100644 --- a/src/kernel/syscalls.c +++ b/src/kernel/syscalls.c @@ -147,8 +147,6 @@ long _sys_mount(hid_t hid, const char __user *path, long len) { mount->refs = 1; proc_cur->mount = mount; - kmalloc_sanity(mount); - kmalloc_sanity(mount->prefix); SYSCALL_RETURN(0); fail: |