arena: add __arena_create() and __arena_destroy() These are lower level interfaces where the caller handles memory. If you want any half-way usable self-sourced arena, you're going to embed it in another struct, and container_of() to that struct in the arena alloc/free funcs. Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
diff --git a/kern/include/arena.h b/kern/include/arena.h index 0f49c74..1c35c9f 100644 --- a/kern/include/arena.h +++ b/kern/include/arena.h
@@ -104,6 +104,12 @@ /* Adds segment [@base, @base + @size) to @arena. */ void *arena_add(struct arena *arena, void *base, size_t size, int flags); void arena_destroy(struct arena *arena); +/* Lower-level create/destroy interface; caller manages the memory */ +void __arena_create(struct arena *arena, const char *name, size_t quantum, + void *(*afunc)(struct arena *, size_t, int), + void (*ffunc)(struct arena *, void *, size_t), + struct arena *source, size_t qcache_max); +void __arena_destroy(struct arena *arena); void *arena_alloc(struct arena *arena, size_t size, int flags); void arena_free(struct arena *arena, void *addr, size_t size);
diff --git a/kern/src/arena.c b/kern/src/arena.c index c23ac41..75d7cd6 100644 --- a/kern/src/arena.c +++ b/kern/src/arena.c
@@ -182,10 +182,10 @@ arena->qcaches = NULL; } -static void arena_init(struct arena *arena, const char *name, size_t quantum, - void *(*afunc)(struct arena *, size_t, int), - void (*ffunc)(struct arena *, void *, size_t), - struct arena *source, size_t qcache_max) +void __arena_create(struct arena *arena, const char *name, size_t quantum, + void *(*afunc)(struct arena *, size_t, int), + void (*ffunc)(struct arena *, void *, size_t), + struct arena *source, size_t qcache_max) { static_assert((ARENA_ALLOC_STYLES & MEM_FLAGS) == 0); @@ -262,7 +262,7 @@ arena = kmalloc(sizeof(struct arena), flags); if (!arena) return 0; - arena_init(arena, name, quantum, afunc, ffunc, source, qcache_max); + __arena_create(arena, name, quantum, afunc, ffunc, source, qcache_max); if (base) { if (!arena_add(arena, base, size, flags)) { warn("Failed to add base to arena %s, aborting!", @@ -290,7 +290,7 @@ return false; } -void arena_destroy(struct arena *arena) +void __arena_destroy(struct arena *arena) { struct btag *bt_i, *temp; @@ -339,6 +339,11 @@ /* Now the remaining BTs are the first on their page. */ BSD_LIST_FOREACH_SAFE(bt_i, &arena->unused_btags, misc_link, temp) arena_free(find_my_base(arena), bt_i, PGSIZE); +} + +void arena_destroy(struct arena *arena) +{ + __arena_destroy(arena); kfree(arena); } @@ -1397,7 +1402,7 @@ static_assert(sizeof(struct arena) + 2 * sizeof(struct btag) <= PGSIZE); - arena_init(a, name, quantum, afunc, ffunc, source, qcache_max); + __arena_create(a, name, quantum, afunc, ffunc, source, qcache_max); if (!source) a->is_base = TRUE; BSD_LIST_INSERT_HEAD(&a->unused_btags, &two_tags[0], misc_link);