arena: add __arena_create() and __arena_destroy()
authorBarret Rhoden <brho@cs.berkeley.edu>
Wed, 2 Oct 2019 18:47:02 +0000 (14:47 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Tue, 8 Oct 2019 21:11:11 +0000 (17:11 -0400)
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>
kern/include/arena.h
kern/src/arena.c

index 0f49c74..1c35c9f 100644 (file)
@@ -104,6 +104,12 @@ struct arena *arena_create(const char *name, void *base, size_t size,
 /* 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);
index c23ac41..75d7cd6 100644 (file)
@@ -182,10 +182,10 @@ static void destroy_qcaches(struct arena *arena)
        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 @@ struct arena *arena_create(const char *name, void *base, size_t size,
        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 @@ static bool __has_importer(struct arena *arena)
        return false;
 }
 
-void arena_destroy(struct arena *arena)
+void __arena_destroy(struct arena *arena)
 {
        struct btag *bt_i, *temp;
 
@@ -339,6 +339,11 @@ void arena_destroy(struct arena *arena)
        /* 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 @@ struct arena *arena_builder(void *pgaddr, const char *name, size_t quantum,
 
        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);