summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2025-05-06 12:36:27 -0400
committerFreya Murphy <freya@freyacat.org>2025-05-06 12:36:27 -0400
commitfa745d64c62e150b2391e8d60e0da261d02aac9f (patch)
tree80d6b529dff137cd7f777e6c49b1f964038c47b8
parentvirt alloc fixes (diff)
downloadcomus-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.c156
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);
}