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);