commit 2033c875fcbcd0c21d1adf3f92d2d1d42a2ceeb6
parent e50c1e28650f983df0cb19b58918b4973f2edaa0
Author: sin <sin@2f30.org>
Date:   Tue, 16 Jul 2013 22:33:58 +0100
Add arenas
Diffstat:
2 files changed, 109 insertions(+), 0 deletions(-)
diff --git a/include/arenas.h b/include/arenas.h
@@ -0,0 +1,11 @@
+#ifndef __ARENAS_H
+#define __ARENAS_H
+
+typedef int arena_id;
+
+struct arenas *arenas_init(void);
+void arenas_free(struct arenas *arenas);
+void *arena_alloc(struct arenas *arenas, size_t n, arena_id id);
+void arena_free(struct arenas *arenas, arena_id id);
+
+#endif	/* __ARENAS_H */
diff --git a/kernel/arenas.c b/kernel/arenas.c
@@ -0,0 +1,98 @@
+#include <kernel.h>
+#include <mmu.h>
+#include <alloc.h>
+#include <arenas.h>
+
+struct arena {
+	arena_id id;
+	void *mem;
+	size_t siz;
+	int used;
+};
+
+struct arenas {
+	struct arena *arena;
+	size_t siz;
+};
+
+static int ndebug = 0;
+
+struct arenas *
+arenas_init(void)
+{
+	struct arenas *arenas;
+
+	arenas = kmalloc(sizeof(struct arenas));
+	if (!arenas)
+		return NULL;
+	arenas->arena = NULL;
+	arenas->siz = 0;
+	return arenas;
+}
+
+void
+arenas_free(struct arenas *arenas)
+{
+	struct arena *arena;
+	size_t i;
+
+	for (i = 0; i < arenas->siz; i++) {
+		arena = &arenas->arena[i];
+		kfree(arena->mem);
+	}
+	kfree(arenas->arena);
+	kfree(arenas);
+}
+
+void *
+arena_alloc(struct arenas *arenas, size_t n, arena_id id)
+{
+	struct arena *tmp;
+	struct arena *arena;
+	size_t i;
+
+	for (i = 0; i < arenas->siz; i++) {
+		arena = &arenas->arena[i];
+		if (arena->id == id) {
+			if (ndebug > 0)
+				kprintf("Found possible unused arena:%d\n", arena->id);
+			if (!arena->used && arena->siz >= n) {
+				if (ndebug > 0)
+					kprintf("Found unused arena:%d of size %zu bytes\n",
+					       arena->id, arena->siz);
+				arena->used = 1;
+				return arena->mem;
+			}
+		}
+	}
+
+	if (ndebug > 0)
+		kprintf("Allocating new arena:%d of size %zu bytes\n",
+		       id, n);
+
+	tmp = krealloc(arenas->arena, sizeof(struct arena) * (arenas->siz + 1));
+	if (!tmp)
+		panic("out of memory");
+	arenas->arena = tmp;
+	arena = &arenas->arena[arenas->siz];
+	arena->id = id;
+	arena->mem = kmalloc(n);
+	if (!arena->mem)
+		panic("out of memory");
+	arena->siz = n;
+	arenas->siz++;
+	return arena->mem;
+}
+
+void
+arena_free(struct arenas *arenas, arena_id id)
+{
+	struct arena *arena;
+	size_t i;
+
+	for (i = 0; i < arenas->siz; i++) {
+		arena = &arenas->arena[i];
+		if (arena->id == id)
+			arena->used = 0;
+	}
+}