summaryrefslogtreecommitdiff
path: root/src/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel')
-rw-r--r--src/kernel/malloc.c107
-rw-r--r--src/kernel/malloc.h1
-rw-r--r--src/kernel/syscalls.c2
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: