From 57a0c665b48cfac9e4741d73177db6a6d7ac4542 Mon Sep 17 00:00:00 2001 From: Miles Rout Date: Fri, 28 Aug 2020 17:49:15 +1200 Subject: [PATCH] Rework alloc_slab into slab_pool --- include/alloc_slab.v.h | 27 -------- include/slab_pool.v.h | 19 ++++++ src/alloc_slab.c | 146 ----------------------------------------- src/slab_pool.c | 99 ++++++++++++++++++++++++++++ src/vine.c | 64 ++++++++++++++++-- 5 files changed, 175 insertions(+), 180 deletions(-) delete mode 100644 include/alloc_slab.v.h create mode 100644 include/slab_pool.v.h delete mode 100644 src/alloc_slab.c create mode 100644 src/slab_pool.c diff --git a/include/alloc_slab.v.h b/include/alloc_slab.v.h deleted file mode 100644 index dd1e479..0000000 --- a/include/alloc_slab.v.h +++ /dev/null @@ -1,27 +0,0 @@ -//require alloc.h -//require alloc_buf.h -//provide alloc_slab.h -struct slab { - struct slab *slab_next; - struct buf_alloc slab_alloc; -#ifdef __GNUC__ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wpedantic" -#endif - char slab_buf[0]; -#ifdef __GNUC__ -#pragma GCC diagnostic pop -#endif -}; -#define SLAB_HEADER_SIZE (sizeof(struct slab) - 1) -struct slab_alloc { - size_t sa_align, sa_size; - void (*sa_init)(void *); - void (*sa_finish)(void *); - struct slab *sa_slabs; -}; -extern void slab_alloc_init(struct slab_alloc *, size_t, size_t, void (*)(void *), void (*)(void *)); -extern void slab_alloc_finish(struct slab_alloc *); -extern void *slab_object_create(struct slab_alloc *); -extern void slab_object_destroy(struct slab_alloc *, void *); -extern void test_slab(void); diff --git a/include/slab_pool.v.h b/include/slab_pool.v.h new file mode 100644 index 0000000..afc0f7d --- /dev/null +++ b/include/slab_pool.v.h @@ -0,0 +1,19 @@ +//require alloc.h +//require alloc_buf.h +//provide slab_pool.h +struct slab { + struct slab *slab_next; + struct buf_alloc slab_ba; + char slab_buf[1]; +}; +#define SLAB_HEADER_SIZE (sizeof(struct slab) - 1) +struct slab_pool { + size_t sp_align, sp_size; + void (*sp_init)(void *ptr); + void (*sp_finish)(void *ptr); + struct slab *sp_slabs; +}; +extern void slab_pool_init(struct slab_pool *, size_t, size_t, void (*)(void *), void (*)(void *)); +extern void slab_pool_finish(struct slab_pool *); +extern void *slab_object_create(struct slab_pool *); +extern void slab_object_destroy(struct slab_pool *, void *); diff --git a/src/alloc_slab.c b/src/alloc_slab.c deleted file mode 100644 index 88ebc8f..0000000 --- a/src/alloc_slab.c +++ /dev/null @@ -1,146 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#ifdef USE_VALGRIND -#include -#endif - -#include "abort.h" -#include "eprintf.h" -#include "alloc.h" -#include "alloc_buf.h" -#include "alloc_slab.h" -#include "memory.h" -#include "log.h" -#include "str.h" -#include "checked.h" - -static struct slab *create_slab(struct slab *next, size_t align); -static void destroy_slab(struct slab *); -static void destroy_slabs(struct slab **); - -void -slab_alloc_init(struct slab_alloc *sa, size_t align, size_t size, - void (*init)(void *), void (*finish)(void *)) -{ - sa->sa_align = align; - sa->sa_size = size; - sa->sa_init = init; - sa->sa_finish = finish; - sa->sa_slabs = NULL; -} - -void -slab_alloc_finish(struct slab_alloc *sa) -{ - destroy_slabs(&sa->sa_slabs); -} - -void * -slab_object_create(struct slab_alloc *sa) -{ - void *ptr; - size_t size = sa->sa_size; - size_t align = sa->sa_align; - - if (sa->sa_slabs == NULL) { - sa->sa_slabs = create_slab(sa->sa_slabs, align); - ptr = allocate_with(&sa->sa_slabs->slab_alloc.ba_alloc, size); - } else { - ptr = try_allocate_with(&sa->sa_slabs->slab_alloc.ba_alloc, size); - if (ptr == NULL) { - sa->sa_slabs = create_slab(sa->sa_slabs, align); - ptr = allocate_with(&sa->sa_slabs->slab_alloc.ba_alloc, size); - } - } - sa->sa_init(ptr); - return ptr; -} - -void -slab_object_destroy(struct slab_alloc *sa, void *ptr) -{ - sa->sa_finish(ptr); -} - -static -struct slab * -create_slab(struct slab *next, size_t align) -{ - char *ptr = allocate_with(&mmap_alloc, PAGE_SIZE); - char *buf = align_ptr(ptr + SLAB_HEADER_SIZE, align); - struct slab *slab = (struct slab *)ptr; - slab->slab_next = next; - buf_alloc_init(&slab->slab_alloc, buf, (size_t)(ptr + PAGE_SIZE - buf)); - return slab; -} - -static -void -destroy_slabs(struct slab **slabs) -{ - while (*slabs) { - struct slab *next = (*slabs)->slab_next; - destroy_slab(*slabs); - *slabs = next; - } -} - -static -void -destroy_slab(struct slab *slab) -{ - deallocate_with(&mmap_alloc, slab, PAGE_SIZE); -} - -#define FOO_ALIGN __alignof__(struct foo) -#define FOO_SIZE sizeof(struct foo) - -/* __attribute__((__packed__)) */ -struct foo { - struct string str; - size_t y; - char x; -}; - -static -void -foo_init(void *foo) -{ - eprintf("foo_init %p\n", foo); - string_init(&((struct foo *)foo)->str); -} - -static -void -foo_finish(void *foo) -{ - eprintf("foo_finish %p\n", foo); - string_finish(&((struct foo *)foo)->str); -} - -void -test_slab(void) -{ - struct slab_alloc sa; - struct foo *f[3]; - - slab_alloc_init(&sa, FOO_ALIGN, FOO_SIZE, &foo_init, &foo_finish); - - eprintf("FOO_ALIGN=%lu\n", FOO_ALIGN); - eprintf("FOO_SIZE=%lu\n", FOO_SIZE); - - f[0] = slab_object_create(&sa); - f[1] = slab_object_create(&sa); - f[2] = slab_object_create(&sa); - slab_object_destroy(&sa, f[0]); - slab_object_destroy(&sa, f[1]); - slab_object_destroy(&sa, f[2]); - - slab_alloc_finish(&sa); -} diff --git a/src/slab_pool.c b/src/slab_pool.c new file mode 100644 index 0000000..ba49771 --- /dev/null +++ b/src/slab_pool.c @@ -0,0 +1,99 @@ +#include +#include +#include +#include +#include +#include +#include + +#ifdef VINE_USE_VALGRIND +#include +#endif + +#include "abort.h" +#include "eprintf.h" +#include "alloc.h" +#include "alloc_buf.h" +#include "slab_pool.h" +#include "memory.h" +#include "log.h" +#include "str.h" +#include "checked.h" + +static struct slab *create_slab(struct slab *next, size_t align); +static void destroy_slab(struct slab *); +static void destroy_slabs(struct slab **); + +void +slab_pool_init(struct slab_pool *sp, size_t align, size_t size, + void (*init)(void *), void (*finish)(void *)) +{ + sp->sp_align = align; + sp->sp_size = size; + sp->sp_init = init; + sp->sp_finish = finish; + sp->sp_slabs = NULL; +} + +void +slab_pool_finish(struct slab_pool *sp) +{ + destroy_slabs(&sp->sp_slabs); +} + +void * +slab_object_create(struct slab_pool *sp) +{ + void *ptr; + size_t size = sp->sp_size; + size_t align = sp->sp_align; + + if (sp->sp_slabs == NULL) { + sp->sp_slabs = create_slab(sp->sp_slabs, align); + ptr = allocate_with(&sp->sp_slabs->slab_ba.ba_alloc, size); + } else { + ptr = try_allocate_with(&sp->sp_slabs->slab_ba.ba_alloc, size); + if (ptr == NULL) { + sp->sp_slabs = create_slab(sp->sp_slabs, align); + ptr = allocate_with(&sp->sp_slabs->slab_ba.ba_alloc, size); + } + } + sp->sp_init(ptr); + return ptr; +} + +void +slab_object_destroy(struct slab_pool *sp, void *ptr) +{ + sp->sp_finish(ptr); +} + +static +struct slab * +create_slab(struct slab *next, size_t align) +{ + char *ptr = allocate_with(&mmap_alloc, PAGE_SIZE); + char *buf = align_ptr(ptr + SLAB_HEADER_SIZE, align); + struct slab *slab = (struct slab *)ptr; + slab->slab_next = next; + buf_alloc_init(&slab->slab_ba, buf, (size_t)(ptr + PAGE_SIZE - buf)); + return slab; +} + +static +void +destroy_slabs(struct slab **slabs) +{ + while (*slabs) { + struct slab *next = (*slabs)->slab_next; + destroy_slab(*slabs); + *slabs = next; + } +} + +static +void +destroy_slab(struct slab *slab) +{ + deallocate_with(&mmap_alloc, slab, PAGE_SIZE); +} diff --git a/src/vine.c b/src/vine.c index 562c36d..6b97b5a 100644 --- a/src/vine.c +++ b/src/vine.c @@ -13,6 +13,7 @@ #include "memory.h" #include "alloc.h" #include "alloc_buf.h" +#include "slab_pool.h" #include "str.h" #include "hash.h" #include "fibre.h" @@ -20,7 +21,6 @@ #include "object.h" #include "table.h" #include "heapstring.h" -#include "alloc_slab.h" #define STACK_SIZE (4 * 1024 * 1024) @@ -84,21 +84,22 @@ test_fibre(void) fibre_return(); } +static void test_slab(void); + int main(void) { + size_t page_size; counter = 0; log_init(); log_set_loglevel(LOG_INFO); log_set_system_loglevel("alloc_buf", LOG_DEBUG); - { - size_t page_size = (size_t)sysconf(_SC_PAGESIZE); - if (page_size != PAGE_SIZE) { - abort_with_error("Page size must be %lu, but is %lu\n", - PAGE_SIZE, page_size); - } + page_size = (size_t)sysconf(_SC_PAGESIZE); + if (page_size != PAGE_SIZE) { + abort_with_error("Page size must be %lu, but is %lu\n", + PAGE_SIZE, page_size); } test_slab(); @@ -187,3 +188,52 @@ main(void) log_finish(); return 0; } + +#define FOO_ALIGN __alignof__(struct foo) +#define FOO_SIZE sizeof(struct foo) + +struct foo { + struct string str; + char x; + size_t y; + char z; +}; + +static +void +foo_init(void *foo) +{ + eprintf("foo_init %p\n", foo); + string_init((struct string *)foo); + eprintf("foo_init %d\n", *(int*)foo); +} + +static +void +foo_finish(void *foo) +{ + eprintf("foo_finish %p\n", foo); + string_finish((struct string *)foo); +} + +static +void +test_slab(void) +{ + struct slab_pool sa; + struct foo *f[3]; + + slab_pool_init(&sa, FOO_ALIGN, FOO_SIZE, &foo_init, &foo_finish); + + eprintf("FOO_ALIGN=%lu\n", FOO_ALIGN); + eprintf("FOO_SIZE=%lu\n", FOO_SIZE); + + f[0] = slab_object_create(&sa); + f[1] = slab_object_create(&sa); + f[2] = slab_object_create(&sa); + slab_object_destroy(&sa, f[0]); + slab_object_destroy(&sa, f[1]); + slab_object_destroy(&sa, f[2]); + + slab_pool_finish(&sa); +} -- 2.45.2