aboutsummaryrefslogtreecommitdiff
path: root/src/lib/libc/malloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libc/malloc.c')
-rw-r--r--src/lib/libc/malloc.c70
1 files changed, 70 insertions, 0 deletions
diff --git a/src/lib/libc/malloc.c b/src/lib/libc/malloc.c
new file mode 100644
index 0000000..cb983fd
--- /dev/null
+++ b/src/lib/libc/malloc.c
@@ -0,0 +1,70 @@
+#include <kogata/malloc.h>
+#include <kogata/slab_alloc.h>
+
+#include <kogata/syscall.h>
+#include <kogata/region_alloc.h>
+
+#include <string.h>
+
+static void* heap_alloc_pages(size_t s) {
+ void* addr = region_alloc(s, "Heap");
+ if (addr == 0) return 0;
+
+ bool map_ok = mmap(addr, s, FM_READ | FM_WRITE);
+ if (!map_ok) {
+ region_free(addr);
+ return 0;
+ }
+
+ return addr;
+}
+
+static void heap_free_pages(void* addr) {
+ munmap(addr);
+ region_free(addr);
+}
+
+static mem_allocator_t *mem_allocator;
+static slab_type_t slab_sizes[] = {
+ { "8B malloc objects", 8, 2 },
+ { "16B malloc objects", 16, 2 },
+ { "32B malloc objects", 32, 2 },
+ { "64B malloc objects", 64, 4 },
+ { "128B malloc objects", 128, 4 },
+ { "256B malloc objects", 256, 4 },
+ { "512B malloc objects", 512, 8 },
+ { "1KB malloc objects", 1024, 8 },
+ { "2KB malloc objects", 2048, 16 },
+ { "4KB malloc objects", 4096, 16 },
+ { 0, 0, 0 }
+};
+
+bool mmap_single_page(void* addr) {
+ return mmap(addr, PAGE_SIZE, MM_READ | MM_WRITE);
+}
+
+void malloc_setup() {
+ region_allocator_init((void*)0x40000000, (void*)0x40000000, (void*)0xB0000000, mmap_single_page);
+
+ mem_allocator = create_slab_allocator(slab_sizes, heap_alloc_pages, heap_free_pages);
+
+ ASSERT(mem_allocator != 0);
+}
+
+void* malloc(size_t size) {
+ if (size == 0) return 0;
+
+ return slab_alloc(mem_allocator, size);
+}
+
+void* calloc(size_t nmemb, size_t sz) {
+ void* r = malloc(nmemb * sz);
+ if (r != 0) memset(r, 0, nmemb * sz);
+ return r;
+}
+
+void free(void* ptr) {
+ slab_free(mem_allocator, ptr);
+}
+
+/* vim: set ts=4 sw=4 tw=0 noet :*/