diff options
Diffstat (limited to 'lib/resource.c')
-rw-r--r-- | lib/resource.c | 133 |
1 files changed, 117 insertions, 16 deletions
diff --git a/lib/resource.c b/lib/resource.c index 5d4c7780..9a4c7717 100644 --- a/lib/resource.c +++ b/lib/resource.c @@ -14,6 +14,8 @@ #include "nest/bird.h" #include "lib/resource.h" #include "lib/string.h" +#include "lib/rcu.h" +#include "lib/io-loop.h" /** * DOC: Resource pools @@ -29,12 +31,6 @@ * is freed upon shutdown of the module. */ -struct pool { - resource r; - list inside; - const char *name; -}; - static void pool_dump(resource *); static void pool_free(resource *); static resource *pool_lookup(resource *, unsigned long); @@ -56,26 +52,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) { @@ -83,14 +92,25 @@ pool_free(resource *P) xfree(r); r = rr; } + + 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) @@ -98,10 +118,47 @@ pool_dump(resource *P) indent -= 3; } -static struct resmem -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 struct resmem +pool_memsize_locked(pool *p) +{ resource *r; struct resmem sum = { .effective = 0, @@ -118,6 +175,46 @@ pool_memsize(resource *P) return sum; } +static struct resmem +pool_memsize(resource *P) +{ + pool *p = (pool *) P; + + pool *parent = pool_parent; + pool_parent = p; + + if (p->loop != parent->loop) + birdloop_enter(p->loop); + + struct resmem sum = pool_memsize_locked(p); + + if (p->loop != parent->loop) + birdloop_leave(p->loop); + + pool_parent = parent; + + return sum; +} + +struct resmem +rp_memsize(pool *p) +{ + int inside = birdloop_inside(p->loop); + if (!inside) + birdloop_enter(p->loop); + + ASSERT_DIE(pool_parent == NULL); + pool_parent = p; + struct resmem 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) { @@ -228,12 +325,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; } @@ -270,6 +370,8 @@ rlookup(unsigned long a) void resource_init(void) { + rcu_init(); + root_pool.r.class = &pool_class; root_pool.name = "Root"; init_list(&root_pool.inside); @@ -440,7 +542,6 @@ mb_free(void *m) } - #define STEP_UP(x) ((x) + (x)/2 + 4) void |