diff options
author | Maria Matejka <mq@ucw.cz> | 2021-11-30 18:16:49 +0100 |
---|---|---|
committer | Maria Matejka <mq@ucw.cz> | 2021-11-30 21:38:25 +0100 |
commit | 385b3ea3956aefc2868cdd838fc0a90f1d8a7857 (patch) | |
tree | d954b853724153e4a2411d57be5f29e5b9236251 /lib/resource.c | |
parent | ab0994a10c26bd76b4154a675267d96d19dfb509 (diff) |
For safer memory allocations, resources are bound to loops.
Also all loops have their basic resource pool for allocations which are
auto-freed when the loop is stopping.
Diffstat (limited to 'lib/resource.c')
-rw-r--r-- | lib/resource.c | 130 |
1 files changed, 114 insertions, 16 deletions
diff --git a/lib/resource.c b/lib/resource.c index 0651406f..c847d41a 100644 --- a/lib/resource.c +++ b/lib/resource.c @@ -14,6 +14,7 @@ #include "lib/resource.h" #include "lib/string.h" #include "lib/rcu.h" +#include "lib/io-loop.h" /** * DOC: Resource pools @@ -29,13 +30,6 @@ * is freed upon shutdown of the module. */ -struct pool { - resource r; - list inside; - struct pool_pages *pages; - const char *name; -}; - struct pool_pages { uint free; uint used; @@ -68,26 +62,39 @@ static int indent; /** * rp_new - create a resource pool * @p: parent pool + * @l: loop to assign * @name: pool name (to be included in debugging dumps) * * rp_new() creates a new resource pool inside the specified * parent pool. */ pool * -rp_new(pool *p, const char *name) +rp_new(pool *p, struct birdloop *loop, const char *name) { + ASSERT_DIE(birdloop_inside(p->loop)); + ASSERT_DIE(birdloop_inside(loop)); + pool *z = ralloc(p, &pool_class); + z->loop = loop; z->name = name; init_list(&z->inside); return z; } +_Thread_local static pool *pool_parent = NULL; + static void pool_free(resource *P) { + ASSERT_DIE(pool_parent); + pool *p = (pool *) P; - resource *r, *rr; + ASSERT_DIE(birdloop_inside(p->loop)); + + pool *parent = pool_parent; + pool_parent = p; + resource *r, *rr; r = HEAD(p->inside); while (rr = (resource *) r->n.next) { @@ -105,14 +112,25 @@ pool_free(resource *P) free_sys_page(p->pages); } + + pool_parent = parent; +} + +void +rp_free(pool *p, pool *parent) +{ + ASSERT_DIE(pool_parent == NULL); + pool_parent = parent; + rfree(p); + ASSERT_DIE(pool_parent == parent); + pool_parent = NULL; } static void -pool_dump(resource *P) +pool_dump_locked(pool *p) { - pool *p = (pool *) P; resource *r; - + debug("%s\n", p->name); indent += 3; WALK_LIST(r, p->inside) @@ -120,10 +138,47 @@ pool_dump(resource *P) indent -= 3; } -static size_t -pool_memsize(resource *P) +static void +pool_dump(resource *P) { pool *p = (pool *) P; + + if (p->loop != pool_parent->loop) + birdloop_enter(p->loop); + + pool *parent = pool_parent; + pool_parent = p; + + pool_dump_locked(p); + + pool_parent = parent; + + if (p->loop != pool_parent->loop) + birdloop_leave(p->loop); +} + +void +rp_dump(pool *p) +{ + int inside = birdloop_inside(p->loop); + if (!inside) + birdloop_enter(p->loop); + + ASSERT_DIE(pool_parent == NULL); + pool_parent = p; + + pool_dump_locked(p); + + ASSERT_DIE(pool_parent == p); + pool_parent = NULL; + + if (!inside) + birdloop_leave(p->loop); +} + +static size_t +pool_memsize_locked(pool *p) +{ resource *r; size_t sum = sizeof(pool) + ALLOC_OVERHEAD; @@ -136,6 +191,46 @@ pool_memsize(resource *P) return sum; } +static size_t +pool_memsize(resource *P) +{ + pool *p = (pool *) P; + + pool *parent = pool_parent; + pool_parent = p; + + if (p->loop != parent->loop) + birdloop_enter(p->loop); + + size_t sum = pool_memsize_locked(p); + + if (p->loop != parent->loop) + birdloop_leave(p->loop); + + pool_parent = parent; + + return sum; +} + +size_t +rp_memsize(pool *p) +{ + int inside = birdloop_inside(p->loop); + if (!inside) + birdloop_enter(p->loop); + + ASSERT_DIE(pool_parent == NULL); + pool_parent = p; + size_t sum = pool_memsize_locked(p); + ASSERT_DIE(pool_parent == p); + pool_parent = NULL; + + if (!inside) + birdloop_leave(p->loop); + + return sum; +} + static resource * pool_lookup(resource *P, unsigned long a) { @@ -243,12 +338,15 @@ rmemsize(void *res) void * ralloc(pool *p, struct resclass *c) { + ASSERT_DIE(p); + ASSERT_DIE(birdloop_inside(p->loop)); + resource *r = xmalloc(c->size); bzero(r, c->size); r->class = c; - if (p) - add_tail(&p->inside, &r->n); + add_tail(&p->inside, &r->n); + return r; } |