diff options
author | Freya Murphy <freya@freyacat.org> | 2025-05-06 12:36:27 -0400 |
---|---|---|
committer | Freya Murphy <freya@freyacat.org> | 2025-05-06 12:36:27 -0400 |
commit | fa745d64c62e150b2391e8d60e0da261d02aac9f (patch) | |
tree | 80d6b529dff137cd7f777e6c49b1f964038c47b8 | |
parent | virt alloc fixes (diff) | |
download | comus-fa745d64c62e150b2391e8d60e0da261d02aac9f.tar.gz comus-fa745d64c62e150b2391e8d60e0da261d02aac9f.tar.bz2 comus-fa745d64c62e150b2391e8d60e0da261d02aac9f.zip |
kernel alloc should not be doing all of this, make it simpler (and work)
Diffstat (limited to '')
-rw-r--r-- | kernel/lib/kalloc.c | 156 |
1 files changed, 14 insertions, 142 deletions
diff --git a/kernel/lib/kalloc.c b/kernel/lib/kalloc.c index f4cd097..23b8b73 100644 --- a/kernel/lib/kalloc.c +++ b/kernel/lib/kalloc.c @@ -1,123 +1,38 @@ -#include "lib/kio.h" #include <lib.h> #include <comus/memory.h> #define MAGIC 0xBEEFCAFE struct page_header { - struct page_header *next; - struct page_header *prev; - size_t - node_number; // all headers on the same page alloc have the same node number (so they can be merged) - size_t - free; // free space after the node (if its the last node in the alloc block) - size_t used; // how much space this allocation is using + size_t len; uint64_t magic; }; -static const size_t header_len = sizeof(struct page_header); -static struct page_header *start_header = NULL; -static struct page_header *end_header = NULL; - static struct page_header *get_header(void *ptr) { struct page_header *header = - (struct page_header *)((uintptr_t)ptr - header_len); + (struct page_header *)((uintptr_t)ptr - PAGE_SIZE); - // PERF: do we want to make sure this pointer is paged - // before reading it??? - if (header->magic != MAGIC) { + if (header->magic != MAGIC) return NULL; // invalid pointer - } return header; } -static void *alloc_new(size_t size) +void *kalloc(size_t size) { - size_t pages = ((size + header_len + PAGE_SIZE - 1) / PAGE_SIZE); - - void *addr = kalloc_pages(pages); - void *mem = (char *)addr + header_len; - - size_t total = pages * PAGE_SIZE; - size_t free = total - (size + header_len); + struct page_header *header; + size_t pages; - if (addr == NULL) { + pages = (size + PAGE_SIZE - 1) / PAGE_SIZE; + header = kalloc_pages(pages + 1); + if (header == NULL) return NULL; - } - size_t node; - if (end_header != NULL) { - node = end_header->node_number + 1; - } else { - node = 0; - } - - struct page_header *header = addr; - memsetv(header, 0, sizeof(struct page_header)); header->magic = MAGIC; - header->used = size; - header->free = free; - header->prev = end_header; - header->next = NULL; - header->node_number = node; - - if (start_header == NULL) { - start_header = header; - } - - if (end_header != NULL) { - end_header->next = header; - } else { - end_header = header; - } + header->len = size; - return mem; -} - -static void *alloc_block(size_t size, struct page_header *block) -{ - struct page_header *header = - (struct page_header *)((char *)block + block->used + header_len); - - size_t free = block->free - (size + header_len); - block->free = 0; - - header->magic = MAGIC; - header->used = size; - header->free = free; - header->prev = block; - header->next = block->next; - block->next = header; - if (header->next) - header->next->prev = header; - header->node_number = block->node_number; - - void *mem = (char *)header + header_len; - - return mem; -} - -void *kalloc(size_t size) -{ - struct page_header *header = start_header; - - for (; header != NULL; header = header->next) { - size_t free = header->free; - if (free < header_len) - continue; - if (size <= - (free - header_len)) { // we must be able to fit data + header - break; - } - } - - if (header != NULL) { - return alloc_block(size, header); - } else { - return alloc_new(size); - } + return (char *)header + PAGE_SIZE; } void *krealloc(void *src, size_t dst_len) @@ -143,7 +58,7 @@ void *krealloc(void *src, size_t dst_len) if (header == NULL) return NULL; - src_len = header->used; + src_len = header->len; if (src_len == 0) return NULL; @@ -164,7 +79,7 @@ void *krealloc(void *src, size_t dst_len) void kfree(void *ptr) { - struct page_header *header, *neighbor; + struct page_header *header; if (ptr == NULL) return; @@ -174,48 +89,5 @@ void kfree(void *ptr) if (header == NULL) return; - header->free += header->used; - header->used = 0; - - // merge left - for (neighbor = header->prev; neighbor != NULL; neighbor = neighbor->prev) { - if (neighbor->node_number != header->node_number) - break; - neighbor->free += header->free + header_len; - neighbor->next = header->next; - if (neighbor->next) - neighbor->next->prev = neighbor; - header = neighbor; - if (header->used) - break; - } - - // merge right - for (neighbor = header->next; neighbor != NULL; neighbor = neighbor->next) { - if (neighbor->node_number != header->node_number) - break; - if (neighbor->used) - break; - header->free += neighbor->free + header_len; - header->next = neighbor->next; - if (header->next) - header->next->prev = header; - } - - // ignore if node on left - if (header->prev != NULL && - header->prev->node_number == header->node_number) - return; - - // ignore if node on right - if (header->next != NULL && - header->next->node_number == header->node_number) - return; - - // ignore if still used - if (header->used) - return; - - // FIXME: huh?! - // kfree_pages(header); + kfree_pages(header); } |