voron

experimental ARM OS
git clone git://git.2f30.org/voron
Log | Files | Refs | README | LICENSE

commit 2033c875fcbcd0c21d1adf3f92d2d1d42a2ceeb6
parent e50c1e28650f983df0cb19b58918b4973f2edaa0
Author: sin <sin@2f30.org>
Date:   Tue, 16 Jul 2013 22:33:58 +0100

Add arenas

Diffstat:
Ainclude/arenas.h | 11+++++++++++
Akernel/arenas.c | 98+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
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; + } +}