mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-11-18 09:08:42 +00:00
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.
This commit is contained in:
parent
ab0994a10c
commit
385b3ea395
@ -89,7 +89,7 @@ int undo_available; /* Undo was not requested from last reconfiguration */
|
||||
struct config *
|
||||
config_alloc(const char *name)
|
||||
{
|
||||
pool *p = rp_new(&root_pool, "Config");
|
||||
pool *p = rp_new(&root_pool, &main_birdloop, "Config");
|
||||
linpool *l = lp_new_default(p);
|
||||
struct config *c = lp_allocz(l, sizeof(struct config));
|
||||
|
||||
@ -196,7 +196,7 @@ void
|
||||
config_free(struct config *c)
|
||||
{
|
||||
if (c)
|
||||
rfree(c->pool);
|
||||
rp_free(c->pool, &root_pool);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -20,7 +20,7 @@ start_conf_env(void)
|
||||
{
|
||||
bt_bird_init();
|
||||
|
||||
pool *p = rp_new(&root_pool, "helper_pool");
|
||||
pool *p = rp_new(&root_pool, &main_birdloop, "helper_pool");
|
||||
linpool *l = lp_new_default(p);
|
||||
cfg_mem = l;
|
||||
}
|
||||
|
@ -57,8 +57,8 @@ t_ev_run_list(void)
|
||||
|
||||
resource_sys_init();
|
||||
resource_init();
|
||||
olock_init();
|
||||
birdloop_init();
|
||||
olock_init();
|
||||
io_init();
|
||||
rt_init();
|
||||
if_init();
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include "test/birdtest.h"
|
||||
#include "lib/flowspec.h"
|
||||
#include "lib/io-loop.h"
|
||||
|
||||
#define NET_ADDR_FLOW4_(what,prefix,pxlen,data_) \
|
||||
do \
|
||||
@ -446,8 +447,6 @@ t_validation6(void)
|
||||
static int
|
||||
t_builder4(void)
|
||||
{
|
||||
resource_init();
|
||||
|
||||
struct flow_builder *fb = flow_builder_init(&root_pool);
|
||||
linpool *lp = lp_new_default(&root_pool);
|
||||
|
||||
@ -529,7 +528,6 @@ t_builder6(void)
|
||||
{
|
||||
net_addr_ip6 ip;
|
||||
|
||||
resource_init();
|
||||
linpool *lp = lp_new_default(&root_pool);
|
||||
struct flow_builder *fb = flow_builder_init(&root_pool);
|
||||
fb->ipv6 = 1;
|
||||
@ -673,6 +671,9 @@ main(int argc, char *argv[])
|
||||
{
|
||||
bt_init(argc, argv);
|
||||
resource_sys_init();
|
||||
resource_init();
|
||||
the_bird_lock();
|
||||
birdloop_init();
|
||||
|
||||
bt_test_suite(t_read_length, "Testing get NLRI length");
|
||||
bt_test_suite(t_write_length, "Testing set NLRI length");
|
||||
@ -688,5 +689,6 @@ main(int argc, char *argv[])
|
||||
bt_test_suite(t_formatting4, "Formatting Flow Specification (IPv4) into text representation");
|
||||
bt_test_suite(t_formatting6, "Formatting Flow Specification (IPv6) into text representation");
|
||||
|
||||
the_bird_unlock();
|
||||
return bt_exit_value();
|
||||
}
|
||||
|
@ -9,7 +9,9 @@
|
||||
#undef LOCAL_DEBUG
|
||||
|
||||
#include "test/birdtest.h"
|
||||
#include "test/bt-utils.h"
|
||||
|
||||
#include "lib/io-loop.h"
|
||||
#include "lib/hash.h"
|
||||
|
||||
struct test_node {
|
||||
@ -61,8 +63,7 @@ dump_nodes(void)
|
||||
static void
|
||||
init_hash_(uint order)
|
||||
{
|
||||
resource_init();
|
||||
my_pool = rp_new(&root_pool, "Test pool");
|
||||
my_pool = rp_new(&root_pool, &main_birdloop, "Test pool");
|
||||
|
||||
HASH_INIT(hash, my_pool, order);
|
||||
|
||||
@ -290,6 +291,7 @@ int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
bt_init(argc, argv);
|
||||
bt_bird_init();
|
||||
|
||||
bt_test_suite(t_insert_find, "HASH_INSERT and HASH_FIND");
|
||||
bt_test_suite(t_insert_find_random, "HASH_INSERT pseudo-random keys and HASH_FIND");
|
||||
|
@ -20,15 +20,15 @@ void sk_reloop(sock *s, struct birdloop *loop);
|
||||
|
||||
extern struct birdloop main_birdloop;
|
||||
|
||||
/* Start a new birdloop owned by given pool and domain */
|
||||
/* Start a new birdloop owned by given pool and domain.
|
||||
* The loop allocates its internal pool for local allocations
|
||||
* which is freed when the loop itself is stopped. */
|
||||
struct birdloop *birdloop_new(pool *p, uint order, const char *name);
|
||||
|
||||
/* Stop the loop. At the end, the @stopped callback is called unlocked in tail
|
||||
* position to finish cleanup. Run birdloop_free() from that callback to free
|
||||
* the loop itself. */
|
||||
/* Stop the loop. At the end, the @stopped callback is called with locked
|
||||
* parent to finish cleanup. The loop then frees itself together with its pool. */
|
||||
void birdloop_stop(struct birdloop *loop, void (*stopped)(void *data), void *data);
|
||||
void birdloop_stop_self(struct birdloop *loop, void (*stopped)(void *data), void *data);
|
||||
void birdloop_free(struct birdloop *loop);
|
||||
|
||||
/* Get birdloop's event list */
|
||||
event_list *birdloop_event_list(struct birdloop *loop);
|
||||
@ -36,6 +36,9 @@ event_list *birdloop_event_list(struct birdloop *loop);
|
||||
/* Get birdloop's time heap */
|
||||
struct timeloop *birdloop_time_loop(struct birdloop *loop);
|
||||
|
||||
/* Get birdloop's resource pool */
|
||||
pool *birdloop_pool(struct birdloop *loop);
|
||||
|
||||
/* Enter and exit the birdloop */
|
||||
void birdloop_enter(struct birdloop *loop);
|
||||
void birdloop_leave(struct birdloop *loop);
|
||||
|
132
lib/resource.c
132
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)
|
||||
{
|
||||
pool *p = (pool *) P;
|
||||
resource *r, *rr;
|
||||
ASSERT_DIE(pool_parent);
|
||||
|
||||
pool *p = (pool *) P;
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -34,10 +34,16 @@ struct resclass {
|
||||
|
||||
/* Generic resource manipulation */
|
||||
|
||||
typedef struct pool pool;
|
||||
typedef struct pool {
|
||||
resource r;
|
||||
list inside;
|
||||
struct pool_pages *pages;
|
||||
struct birdloop *loop;
|
||||
const char *name;
|
||||
} pool;
|
||||
|
||||
void resource_init(void);
|
||||
pool *rp_new(pool *, const char *); /* Create new pool */
|
||||
|
||||
void rfree(void *); /* Free single resource */
|
||||
void rdump(void *); /* Dump to debug output */
|
||||
size_t rmemsize(void *res); /* Return size of memory used by the resource */
|
||||
@ -46,6 +52,11 @@ void rmove(void *, pool *); /* Move to a different pool */
|
||||
|
||||
void *ralloc(pool *, struct resclass *);
|
||||
|
||||
pool *rp_new(pool *, struct birdloop *loop, const char *); /* Create new pool */
|
||||
void rp_free(pool *p, pool *parent); /* Free parent pool */
|
||||
size_t rp_memsize(pool *p); /* Return size of memory used by the pool */
|
||||
void rp_dump(pool *p); /* Dump pool to debug output */
|
||||
|
||||
extern pool root_pool;
|
||||
|
||||
/* Normal memory blocks */
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "nest/route.h"
|
||||
#include "nest/attrs.h"
|
||||
#include "lib/resource.h"
|
||||
#include "lib/io-loop.h"
|
||||
|
||||
#define TESTS_NUM 30
|
||||
#define AS_PATH_LENGTH 1000
|
||||
@ -23,8 +24,6 @@
|
||||
static int
|
||||
t_as_path_match(void)
|
||||
{
|
||||
resource_init();
|
||||
|
||||
int round;
|
||||
for (round = 0; round < TESTS_NUM; round++)
|
||||
{
|
||||
@ -70,8 +69,6 @@ t_as_path_match(void)
|
||||
static int
|
||||
t_path_format(void)
|
||||
{
|
||||
resource_init();
|
||||
|
||||
struct adata empty_as_path = {};
|
||||
struct adata *as_path = &empty_as_path;
|
||||
struct linpool *lp = lp_new_default(&root_pool);
|
||||
@ -116,8 +113,6 @@ count_asn_in_array(const u32 *array, u32 asn)
|
||||
static int
|
||||
t_path_include(void)
|
||||
{
|
||||
resource_init();
|
||||
|
||||
struct adata empty_as_path = {};
|
||||
struct adata *as_path = &empty_as_path;
|
||||
struct linpool *lp = lp_new_default(&root_pool);
|
||||
@ -161,8 +156,6 @@ t_path_include(void)
|
||||
static int
|
||||
t_as_path_converting(void)
|
||||
{
|
||||
resource_init();
|
||||
|
||||
struct adata empty_as_path = {};
|
||||
struct adata *as_path = &empty_as_path;
|
||||
struct linpool *lp = lp_new_default(&root_pool);
|
||||
@ -211,6 +204,9 @@ main(int argc, char *argv[])
|
||||
{
|
||||
bt_init(argc, argv);
|
||||
resource_sys_init();
|
||||
resource_init();
|
||||
the_bird_lock();
|
||||
birdloop_init();
|
||||
|
||||
bt_test_suite(t_as_path_match, "Testing AS path matching and some a-path utilities.");
|
||||
bt_test_suite(t_path_format, "Testing formating as path into byte buffer");
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "nest/route.h"
|
||||
#include "nest/attrs.h"
|
||||
#include "lib/resource.h"
|
||||
#include "lib/io-loop.h"
|
||||
|
||||
#define SET_SIZE 10
|
||||
static const struct adata *set_sequence; /* <0; SET_SIZE) */
|
||||
@ -71,7 +72,6 @@ t_set_int_contains(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
resource_init();
|
||||
generate_set_sequence(SET_TYPE_INT, SET_SIZE);
|
||||
|
||||
bt_assert(int_set_get_size(set_sequence) == SET_SIZE);
|
||||
@ -92,7 +92,6 @@ t_set_int_contains(void)
|
||||
static int
|
||||
t_set_int_union(void)
|
||||
{
|
||||
resource_init();
|
||||
generate_set_sequence(SET_TYPE_INT, SET_SIZE);
|
||||
|
||||
const struct adata *set_union;
|
||||
@ -111,7 +110,6 @@ t_set_int_union(void)
|
||||
static int
|
||||
t_set_int_format(void)
|
||||
{
|
||||
resource_init();
|
||||
generate_set_sequence(SET_TYPE_INT, SET_SIZE_FOR_FORMAT_OUTPUT);
|
||||
|
||||
bt_assert(int_set_format(set_sequence, 0, 0, buf, BUFFER_SIZE) == 0);
|
||||
@ -132,7 +130,6 @@ t_set_int_format(void)
|
||||
static int
|
||||
t_set_int_delete(void)
|
||||
{
|
||||
resource_init();
|
||||
generate_set_sequence(SET_TYPE_INT, SET_SIZE);
|
||||
|
||||
const struct adata *deleting_sequence = set_sequence;
|
||||
@ -160,7 +157,6 @@ t_set_ec_contains(void)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
resource_init();
|
||||
generate_set_sequence(SET_TYPE_EC, SET_SIZE);
|
||||
|
||||
bt_assert(ec_set_get_size(set_sequence) == SET_SIZE);
|
||||
@ -181,7 +177,6 @@ t_set_ec_contains(void)
|
||||
static int
|
||||
t_set_ec_union(void)
|
||||
{
|
||||
resource_init();
|
||||
generate_set_sequence(SET_TYPE_EC, SET_SIZE);
|
||||
|
||||
const struct adata *set_union;
|
||||
@ -200,8 +195,6 @@ t_set_ec_union(void)
|
||||
static int
|
||||
t_set_ec_format(void)
|
||||
{
|
||||
resource_init();
|
||||
|
||||
const struct adata empty_as_path = {};
|
||||
set_sequence = set_sequence_same = set_sequence_higher = set_random = &empty_as_path;
|
||||
lp = lp_new_default(&root_pool);
|
||||
@ -222,7 +215,6 @@ t_set_ec_format(void)
|
||||
static int
|
||||
t_set_ec_delete(void)
|
||||
{
|
||||
resource_init();
|
||||
generate_set_sequence(SET_TYPE_EC, SET_SIZE);
|
||||
|
||||
const struct adata *deleting_sequence = set_sequence;
|
||||
@ -248,6 +240,9 @@ main(int argc, char *argv[])
|
||||
{
|
||||
bt_init(argc, argv);
|
||||
resource_sys_init();
|
||||
resource_init();
|
||||
the_bird_lock();
|
||||
birdloop_init();
|
||||
|
||||
bt_test_suite(t_set_int_contains, "Testing sets of integers: contains, get_data");
|
||||
bt_test_suite(t_set_int_format, "Testing sets of integers: format");
|
||||
|
@ -262,7 +262,7 @@ cli_command(struct cli *c)
|
||||
log(L_TRACE "CLI: %s", c->rx_buf);
|
||||
bzero(&f, sizeof(f));
|
||||
f.mem = c->parser_pool;
|
||||
f.pool = rp_new(c->pool, "Config");
|
||||
f.pool = rp_new(c->pool, &main_birdloop, "Config");
|
||||
init_list(&f.symbols);
|
||||
cf_read_hook = cli_cmd_read_hook;
|
||||
cli_rh_pos = c->rx_buf;
|
||||
@ -308,7 +308,7 @@ cli_event(void *data)
|
||||
cli *
|
||||
cli_new(void *priv)
|
||||
{
|
||||
pool *p = rp_new(cli_pool, "CLI");
|
||||
pool *p = rp_new(cli_pool, &main_birdloop, "CLI");
|
||||
cli *c = mb_alloc(p, sizeof(cli));
|
||||
|
||||
bzero(c, sizeof(cli));
|
||||
@ -413,7 +413,7 @@ cli_free(cli *c)
|
||||
c->cleanup(c);
|
||||
if (c == cmd_reconfig_stored_cli)
|
||||
cmd_reconfig_stored_cli = NULL;
|
||||
rfree(c->pool);
|
||||
rp_free(c->pool, &root_pool);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -425,7 +425,7 @@ cli_free(cli *c)
|
||||
void
|
||||
cli_init(void)
|
||||
{
|
||||
cli_pool = rp_new(&root_pool, "CLI");
|
||||
cli_pool = rp_new(&root_pool, &main_birdloop, "CLI");
|
||||
init_list(&cli_log_hooks);
|
||||
cli_log_inited = 1;
|
||||
}
|
||||
|
@ -88,10 +88,10 @@ void
|
||||
cmd_show_memory(void)
|
||||
{
|
||||
cli_msg(-1018, "BIRD memory usage");
|
||||
print_size("Routing tables:", rmemsize(rt_table_pool));
|
||||
print_size("Route attributes:", rmemsize(rta_pool));
|
||||
print_size("Protocols:", rmemsize(proto_pool));
|
||||
print_size("Total:", rmemsize(&root_pool));
|
||||
print_size("Routing tables:", rp_memsize(rt_table_pool));
|
||||
print_size("Route attributes:", rp_memsize(rta_pool));
|
||||
print_size("Protocols:", rp_memsize(proto_pool));
|
||||
print_size("Total:", rp_memsize(&root_pool));
|
||||
cli_msg(0, "");
|
||||
}
|
||||
|
||||
|
@ -810,7 +810,7 @@ sym_args:
|
||||
|
||||
CF_CLI_HELP(DUMP, ..., [[Dump debugging information]])
|
||||
CF_CLI(DUMP RESOURCES,,, [[Dump all allocated resource]])
|
||||
{ rdump(&root_pool); cli_msg(0, ""); } ;
|
||||
{ rp_dump(&root_pool); cli_msg(0, ""); } ;
|
||||
CF_CLI(DUMP SOCKETS,,, [[Dump open sockets]])
|
||||
{ sk_dump_all(); cli_msg(0, ""); } ;
|
||||
CF_CLI(DUMP EVENTS,,, [[Dump event log]])
|
||||
|
@ -713,7 +713,7 @@ if_choose_router_id(struct iface_patt *mask, u32 old_id)
|
||||
void
|
||||
if_init(void)
|
||||
{
|
||||
if_pool = rp_new(&root_pool, "Interfaces");
|
||||
if_pool = rp_new(&root_pool, &main_birdloop, "Interfaces");
|
||||
init_list(&iface_list);
|
||||
strcpy(default_vrf.name, "default");
|
||||
neigh_init(if_pool);
|
||||
|
41
nest/proto.c
41
nest/proto.c
@ -666,7 +666,10 @@ static uint channel_aux_imex(struct channel_aux_table *cat)
|
||||
static void
|
||||
channel_aux_stopped(void *data)
|
||||
{
|
||||
struct channel_aux_table *cat = data;
|
||||
struct channel_aux_table *cat;
|
||||
RT_LOCKED((rtable *) data, t)
|
||||
cat = t->config->owner;
|
||||
|
||||
struct channel *c = cat->c;
|
||||
|
||||
if (channel_aux_imex(cat))
|
||||
@ -674,7 +677,6 @@ channel_aux_stopped(void *data)
|
||||
else
|
||||
c->in_table = NULL;
|
||||
|
||||
rfree(cat->tab->priv.rp);
|
||||
mb_free(cat);
|
||||
channel_check_stopped(c);
|
||||
}
|
||||
@ -694,7 +696,7 @@ channel_aux_export_stopped(struct rt_export_request *req)
|
||||
|
||||
int del;
|
||||
RT_LOCKED(cat->tab, t)
|
||||
del = !!t->delete_event;
|
||||
del = !!t->delete;
|
||||
|
||||
if (del)
|
||||
return;
|
||||
@ -708,10 +710,7 @@ static void
|
||||
channel_aux_stop(struct channel_aux_table *cat)
|
||||
{
|
||||
RT_LOCKED(cat->tab, t)
|
||||
{
|
||||
t->delete_event = ev_new_init(t->rp, channel_aux_stopped, cat);
|
||||
t->delete_event->list = proto_event_list(cat->c->proto);
|
||||
}
|
||||
t->delete = channel_aux_stopped;
|
||||
|
||||
cat->push_stopped = (event) {
|
||||
.hook = channel_aux_import_stopped,
|
||||
@ -889,6 +888,7 @@ channel_setup_in_table(struct channel *c, int best)
|
||||
|
||||
bsprintf(cat->name, "%s.%s.import", c->proto->name, c->name);
|
||||
|
||||
cat->tab_cf.owner = cat;
|
||||
cat->tab_cf.name = cat->name;
|
||||
cat->tab_cf.addr_type = c->net_type;
|
||||
cat->tab_cf.cork_limit = 4 * page_size / sizeof(struct rt_pending_export);
|
||||
@ -933,6 +933,7 @@ channel_setup_out_table(struct channel *c)
|
||||
|
||||
bsprintf(cat->name, "%s.%s.export", c->proto->name, c->name);
|
||||
|
||||
cat->tab_cf.owner = cat;
|
||||
cat->tab_cf.name = cat->name;
|
||||
cat->tab_cf.addr_type = c->net_type;
|
||||
cat->tab_cf.cork_limit = 4 * page_size / sizeof(struct rt_pending_export);
|
||||
@ -1387,9 +1388,6 @@ proto_configure_channel(struct proto *p, struct channel **pc, struct channel_con
|
||||
static void
|
||||
proto_cleanup(struct proto *p)
|
||||
{
|
||||
rfree(p->pool);
|
||||
p->pool = NULL;
|
||||
|
||||
p->active = 0;
|
||||
proto_log_state_change(p);
|
||||
proto_rethink_goal(p);
|
||||
@ -1400,13 +1398,13 @@ proto_loop_stopped(void *ptr)
|
||||
{
|
||||
struct proto *p = ptr;
|
||||
|
||||
birdloop_enter(&main_birdloop);
|
||||
ASSERT_DIE(birdloop_inside(&main_birdloop));
|
||||
|
||||
p->loop = &main_birdloop;
|
||||
p->pool = NULL;
|
||||
p->event->list = NULL;
|
||||
proto_cleanup(p);
|
||||
|
||||
birdloop_leave(&main_birdloop);
|
||||
proto_cleanup(p);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1426,7 +1424,11 @@ proto_event(void *ptr)
|
||||
if (p->loop != &main_birdloop)
|
||||
birdloop_stop_self(p->loop, proto_loop_stopped, p);
|
||||
else
|
||||
{
|
||||
rp_free(p->pool, proto_pool);
|
||||
p->pool = NULL;
|
||||
proto_cleanup(p);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1490,13 +1492,16 @@ proto_start(struct proto *p)
|
||||
void *nb = mb_alloc(proto_pool, ns);
|
||||
ASSERT_DIE(ns - 1 == bsnprintf(nb, ns, "Protocol %s", p->cf->name));
|
||||
|
||||
p->pool = rp_new(proto_pool, nb);
|
||||
|
||||
if (graceful_restart_state == GRS_INIT)
|
||||
p->gr_recovery = 1;
|
||||
|
||||
if (p->cf->loop_order != DOMAIN_ORDER(the_bird))
|
||||
p->loop = birdloop_new(p->pool, p->cf->loop_order, nb);
|
||||
if (p->cf->loop_order == DOMAIN_ORDER(the_bird))
|
||||
p->pool = rp_new(proto_pool, &main_birdloop, nb);
|
||||
else
|
||||
{
|
||||
p->loop = birdloop_new(proto_pool, p->cf->loop_order, nb);
|
||||
p->pool = birdloop_pool(p->loop);
|
||||
}
|
||||
|
||||
p->event->list = proto_event_list(p);
|
||||
|
||||
@ -2177,7 +2182,7 @@ protos_build(void)
|
||||
proto_build(&proto_perf);
|
||||
#endif
|
||||
|
||||
proto_pool = rp_new(&root_pool, "Protocols");
|
||||
proto_pool = rp_new(&root_pool, &main_birdloop, "Protocols");
|
||||
proto_shutdown_timer = tm_new(proto_pool);
|
||||
proto_shutdown_timer->hook = proto_shutdown_loop;
|
||||
}
|
||||
|
@ -174,7 +174,7 @@ typedef struct rtable_private {
|
||||
struct event *announce_event; /* Event to announce pending exports */
|
||||
struct event *ec_event; /* Event to prune finished exports */
|
||||
struct event *hcu_event; /* Event to update host cache */
|
||||
struct event *delete_event; /* Event to delete the table */
|
||||
void (*delete)(void *); /* Delete callback (in parent loop context) */
|
||||
btime last_rt_change; /* Last time when route changed */
|
||||
btime base_settle_time; /* Start time of rtable settling interval */
|
||||
btime gc_time; /* Time of last GC */
|
||||
@ -212,7 +212,7 @@ typedef union {
|
||||
struct rtable_config {
|
||||
node n;
|
||||
char *name;
|
||||
struct config *config;
|
||||
void *owner; /* Main config if global table, channel_aux_table if channel table */
|
||||
rtable *table;
|
||||
struct proto_config *krt_attached; /* Kernel syncer attached to this table */
|
||||
uint addr_type; /* Type of address data stored in table (NET_*) */
|
||||
|
@ -117,7 +117,7 @@ static void
|
||||
rte_src_init(void)
|
||||
{
|
||||
src_domain = DOMAIN_NEW(attrs, "Route sources");
|
||||
src_pool = rp_new(&root_pool, "Route sources");
|
||||
src_pool = rp_new(&root_pool, &main_birdloop, "Route sources");
|
||||
rte_src_slab = sl_new(src_pool, sizeof(struct rte_src));
|
||||
|
||||
idm_init(&src_ids, src_pool, SRC_ID_INIT_SIZE);
|
||||
@ -1534,7 +1534,7 @@ rta_init(void)
|
||||
{
|
||||
attrs_domain = DOMAIN_NEW(attrs, "Attributes");
|
||||
|
||||
rta_pool = rp_new(&root_pool, "Attributes");
|
||||
rta_pool = rp_new(&root_pool, &main_birdloop, "Attributes");
|
||||
|
||||
rta_slab_[0] = sl_new(rta_pool, sizeof(rta));
|
||||
rta_slab_[1] = sl_new(rta_pool, sizeof(rta) + sizeof(u32));
|
||||
|
@ -1695,7 +1695,7 @@ rt_export_stopped(void *data)
|
||||
RT_LOCKED(hook->table, tab)
|
||||
{
|
||||
/* Free the hook together with its coroutine. */
|
||||
rfree(hook->pool);
|
||||
rp_free(hook->pool, tab->rp);
|
||||
rt_unlock_table(tab);
|
||||
|
||||
DBG("Export hook %p in table %s finished uc=%u\n", hook, tab->name, tab->use_count);
|
||||
@ -1777,7 +1777,7 @@ rt_request_export(rtable *t, struct rt_export_request *req)
|
||||
rtable_private *tab = RT_PRIV(t);
|
||||
rt_lock_table(tab);
|
||||
|
||||
pool *p = rp_new(tab->rp, "Export hook");
|
||||
pool *p = rp_new(tab->rp, tab->loop, "Export hook");
|
||||
struct rt_export_hook *hook = req->hook = mb_allocz(p, sizeof(struct rt_export_hook));
|
||||
hook->pool = p;
|
||||
|
||||
@ -1935,7 +1935,7 @@ rt_dump(rtable *tab)
|
||||
{
|
||||
RT_LOCK(tab);
|
||||
rtable_private *t = RT_PRIV(tab);
|
||||
debug("Dump of routing table <%s>%s\n", t->name, t->delete_event ? " (deleted)" : "");
|
||||
debug("Dump of routing table <%s>%s\n", t->name, t->delete ? " (deleted)" : "");
|
||||
#ifdef DEBUGGING
|
||||
fib_check(&t->fib);
|
||||
#endif
|
||||
@ -1969,7 +1969,7 @@ rt_dump_hooks(rtable *t)
|
||||
{
|
||||
RT_LOCK(t);
|
||||
rtable_private *tab = RT_PRIV(t);
|
||||
debug("Dump of hooks in routing table <%s>%s\n", tab->name, tab->delete_event ? " (deleted)" : "");
|
||||
debug("Dump of hooks in routing table <%s>%s\n", tab->name, tab->delete ? " (deleted)" : "");
|
||||
debug(" nhu_state=%u hcu_scheduled=%u use_count=%d rt_count=%u\n",
|
||||
atomic_load(&tab->nhu_state), ev_active(tab->hcu_event), tab->use_count, tab->rt_count);
|
||||
debug(" last_rt_change=%t gc_time=%t gc_counter=%d prune_state=%u\n",
|
||||
@ -2142,6 +2142,9 @@ rt_free(resource *_r)
|
||||
ASSERT_DIE(EMPTY_LIST(r->imports));
|
||||
ASSERT_DIE(EMPTY_LIST(r->exports));
|
||||
|
||||
if (r->hostcache)
|
||||
rt_free_hostcache(r);
|
||||
|
||||
/* Freed automagically by the resource pool
|
||||
fib_free(&r->fib);
|
||||
hmap_free(&r->id_map);
|
||||
@ -2175,10 +2178,14 @@ rt_setup(pool *pp, struct rtable_config *cf)
|
||||
void *nb = mb_alloc(pp, ns);
|
||||
ASSERT_DIE(ns - 1 == bsnprintf(nb, ns, "Routing table %s", cf->name));
|
||||
|
||||
pool *p = rp_new(pp, nb);
|
||||
struct birdloop *l = birdloop_new(pp, DOMAIN_ORDER(rtable), nb);
|
||||
pool *p = birdloop_pool(l);
|
||||
|
||||
birdloop_enter(l);
|
||||
|
||||
rtable_private *t = ralloc(p, &rt_class);
|
||||
t->rp = p;
|
||||
t->loop = l;
|
||||
|
||||
t->rte_slab = sl_new(p, sizeof(struct rte_storage));
|
||||
|
||||
@ -2197,8 +2204,6 @@ rt_setup(pool *pp, struct rtable_config *cf)
|
||||
init_list(&t->pending_exports);
|
||||
init_list(&t->subscribers);
|
||||
|
||||
t->loop = birdloop_new(p, DOMAIN_ORDER(rtable), nb);
|
||||
|
||||
t->announce_event = ev_new_init(p, rt_announce_exports, t);
|
||||
t->ec_event = ev_new_init(p, rt_export_cleanup, t);
|
||||
t->prune_event = ev_new_init(p, rt_prune_table, t);
|
||||
@ -2216,6 +2221,8 @@ rt_setup(pool *pp, struct rtable_config *cf)
|
||||
t->nhu_lp = lp_new_default(p);
|
||||
|
||||
mb_move(nb, p);
|
||||
birdloop_leave(l);
|
||||
|
||||
return (rtable *) t;
|
||||
}
|
||||
|
||||
@ -2229,7 +2236,7 @@ void
|
||||
rt_init(void)
|
||||
{
|
||||
rta_init();
|
||||
rt_table_pool = rp_new(&root_pool, "Routing tables");
|
||||
rt_table_pool = rp_new(&root_pool, &main_birdloop, "Routing tables");
|
||||
init_list(&routing_tables);
|
||||
ev_init_cork(&rt_cork, "Route Table Cork");
|
||||
}
|
||||
@ -2819,7 +2826,7 @@ rt_new_table(struct symbol *s, uint addr_type)
|
||||
c->min_rr_settle_time = 30 S;
|
||||
c->max_rr_settle_time = 90 S;
|
||||
c->cork_limit = 4 * page_size / sizeof(struct rt_pending_export);
|
||||
c->config = new_config;
|
||||
c->owner = new_config;
|
||||
|
||||
add_tail(&new_config->tables, &c->n);
|
||||
|
||||
@ -2844,18 +2851,6 @@ rt_lock_table(rtable_private *r)
|
||||
r->use_count++;
|
||||
}
|
||||
|
||||
static void
|
||||
rt_loop_stopped(void *data)
|
||||
{
|
||||
rtable_private *r = data;
|
||||
birdloop_free(r->loop);
|
||||
r->loop = NULL;
|
||||
r->prune_event->list = r->ec_event->list = NULL;
|
||||
r->nhu_event->list = r->hcu_event->list = NULL;
|
||||
r->announce_event->list = NULL;
|
||||
ev_send(r->delete_event->list, r->delete_event);
|
||||
}
|
||||
|
||||
/**
|
||||
* rt_unlock_table - unlock a routing table
|
||||
* @r: routing table to be unlocked
|
||||
@ -2867,10 +2862,9 @@ rt_loop_stopped(void *data)
|
||||
void
|
||||
rt_unlock_table(rtable_private *r)
|
||||
{
|
||||
if (!--r->use_count && r->delete_event &&
|
||||
if (!--r->use_count && r->delete &&
|
||||
!r->prune_state && !atomic_load_explicit(&r->nhu_state, memory_order_acquire))
|
||||
/* Delete the routing table by freeing its pool */
|
||||
birdloop_stop_self(r->loop, rt_loop_stopped, r);
|
||||
birdloop_stop_self(r->loop, r->delete, r);
|
||||
}
|
||||
|
||||
static struct rtable_config *
|
||||
@ -2883,22 +2877,16 @@ rt_find_table_config(struct config *cf, char *name)
|
||||
static void
|
||||
rt_done(void *data)
|
||||
{
|
||||
rtable_private *t = data;
|
||||
ASSERT_DIE(t->loop == NULL);
|
||||
RT_LOCKED((rtable *) data, t)
|
||||
{
|
||||
struct rtable_config *tc = t->config;
|
||||
struct config *c = tc->owner;
|
||||
|
||||
struct rtable_config *tc = t->config;
|
||||
struct config *c = tc->config;
|
||||
tc->table = NULL;
|
||||
rem_node(&t->n);
|
||||
|
||||
tc->table = NULL;
|
||||
rem_node(&t->n);
|
||||
|
||||
if (t->hostcache)
|
||||
rt_free_hostcache(t);
|
||||
|
||||
rfree(t->delete_event);
|
||||
rfree(t->rp);
|
||||
|
||||
config_del_obstacle(c);
|
||||
config_del_obstacle(c);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2925,7 +2913,7 @@ rt_commit(struct config *new, struct config *old)
|
||||
{
|
||||
RT_LOCK(o->table);
|
||||
rtable_private *ot = RT_PRIV(o->table);
|
||||
if (!ot->delete_event)
|
||||
if (!ot->delete)
|
||||
{
|
||||
r = rt_find_table_config(new, o->name);
|
||||
if (r && (r->addr_type == o->addr_type) && !new->shutdown)
|
||||
@ -2941,8 +2929,7 @@ rt_commit(struct config *new, struct config *old)
|
||||
{
|
||||
DBG("\t%s: deleted\n", o->name);
|
||||
rt_lock_table(ot);
|
||||
ot->delete_event = ev_new_init(&root_pool, rt_done, ot);
|
||||
ot->delete_event->list = &global_event_list;
|
||||
ot->delete = rt_done;
|
||||
config_add_obstacle(old);
|
||||
rt_unlock_table(ot);
|
||||
}
|
||||
|
@ -1747,7 +1747,7 @@ babel_add_iface(struct babel_proto *p, struct iface *new, struct babel_iface_con
|
||||
|
||||
TRACE(D_EVENTS, "Adding interface %s", new->name);
|
||||
|
||||
pool *pool = rp_new(p->p.pool, new->name);
|
||||
pool *pool = rp_new(p->p.pool, p->p.loop, new->name);
|
||||
|
||||
ifa = mb_allocz(pool, sizeof(struct babel_iface));
|
||||
ifa->proto = p;
|
||||
|
@ -452,8 +452,8 @@ bfd_add_session(struct bfd_proto *p, ip_addr addr, ip_addr local, struct iface *
|
||||
s->passive = s->cf.passive;
|
||||
s->tx_csn = random_u32();
|
||||
|
||||
s->tx_timer = tm_new_init(p->tpool, bfd_tx_timer_hook, s, 0, 0);
|
||||
s->hold_timer = tm_new_init(p->tpool, bfd_hold_timer_hook, s, 0, 0);
|
||||
s->tx_timer = tm_new_init(p->p.pool, bfd_tx_timer_hook, s, 0, 0);
|
||||
s->hold_timer = tm_new_init(p->p.pool, bfd_hold_timer_hook, s, 0, 0);
|
||||
bfd_session_update_tx_interval(s);
|
||||
bfd_session_control_tx_timer(s, 1);
|
||||
|
||||
@ -581,7 +581,7 @@ bfd_get_iface(struct bfd_proto *p, ip_addr local, struct iface *iface)
|
||||
struct bfd_config *cf = (struct bfd_config *) (p->p.cf);
|
||||
struct bfd_iface_config *ic = bfd_find_iface_config(cf, iface);
|
||||
|
||||
ifa = mb_allocz(p->tpool, sizeof(struct bfd_iface));
|
||||
ifa = mb_allocz(p->p.pool, sizeof(struct bfd_iface));
|
||||
ifa->local = local;
|
||||
ifa->iface = iface;
|
||||
ifa->cf = ic;
|
||||
@ -1062,8 +1062,6 @@ bfd_start(struct proto *P)
|
||||
|
||||
pthread_spin_init(&p->lock, PTHREAD_PROCESS_PRIVATE);
|
||||
|
||||
p->tpool = rp_new(P->pool, "BFD loop pool");
|
||||
|
||||
p->session_slab = sl_new(P->pool, sizeof(struct bfd_session));
|
||||
HASH_INIT(p->session_hash_id, P->pool, 8);
|
||||
HASH_INIT(p->session_hash_ip, P->pool, 8);
|
||||
|
@ -90,8 +90,6 @@ struct bfd_proto
|
||||
|
||||
pthread_spinlock_t lock;
|
||||
|
||||
pool *tpool;
|
||||
|
||||
node bfd_node;
|
||||
|
||||
slab *session_slab;
|
||||
|
@ -561,10 +561,11 @@ mrt_rib_table_dump(struct mrt_table_dump_state *s, net *n, int add_path)
|
||||
static struct mrt_table_dump_state *
|
||||
mrt_table_dump_init(pool *pp)
|
||||
{
|
||||
pool *pool = rp_new(pp, "MRT Table Dump");
|
||||
pool *pool = rp_new(pp, &main_birdloop, "MRT Table Dump");
|
||||
struct mrt_table_dump_state *s = mb_allocz(pool, sizeof(struct mrt_table_dump_state));
|
||||
|
||||
s->pool = pool;
|
||||
s->parent = pp;
|
||||
s->linpool = lp_new(pool, 4080);
|
||||
s->peer_lp = lp_new(pool, 4080);
|
||||
mrt_buffer_init(&s->buf, pool, 2 * MRT_ATTR_BUFFER_SIZE);
|
||||
@ -601,7 +602,7 @@ mrt_table_dump_free(struct mrt_table_dump_state *s)
|
||||
|
||||
config_del_obstacle(s->config);
|
||||
|
||||
rfree(s->pool);
|
||||
rp_free(s->pool, s->parent);
|
||||
}
|
||||
|
||||
|
||||
|
@ -67,6 +67,7 @@ struct mrt_table_dump_state {
|
||||
|
||||
/* Allocated by mrt_table_dump_init() */
|
||||
pool *pool; /* Pool for table dump */
|
||||
pool *parent; /* Parent pool for cleanup */
|
||||
linpool *linpool; /* Temporary linear pool */
|
||||
linpool *peer_lp; /* Linear pool for peer entries in peer_hash */
|
||||
buffer buf; /* Buffer for MRT messages */
|
||||
|
@ -311,7 +311,7 @@ ospf_iface_remove(struct ospf_iface *ifa)
|
||||
|
||||
ospf_iface_sm(ifa, ISM_DOWN);
|
||||
rem_node(NODE ifa);
|
||||
rfree(ifa->pool);
|
||||
rp_free(ifa->pool, p->p.pool);
|
||||
}
|
||||
|
||||
void
|
||||
@ -567,7 +567,7 @@ ospf_iface_new(struct ospf_area *oa, struct ifa *addr, struct ospf_iface_patt *i
|
||||
OSPF_TRACE(D_EVENTS, "Adding interface %s (%N) to area %R",
|
||||
iface->name, &addr->prefix, oa->areaid);
|
||||
|
||||
pool = rp_new(p->p.pool, "OSPF Interface");
|
||||
pool = rp_new(p->p.pool, p->p.loop, "OSPF Interface");
|
||||
ifa = mb_allocz(pool, sizeof(struct ospf_iface));
|
||||
ifa->iface = iface;
|
||||
ifa->addr = addr;
|
||||
@ -687,7 +687,7 @@ ospf_iface_new_vlink(struct ospf_proto *p, struct ospf_iface_patt *ip)
|
||||
|
||||
/* Vlink ifname is stored just after the ospf_iface structure */
|
||||
|
||||
pool = rp_new(p->p.pool, "OSPF Vlink");
|
||||
pool = rp_new(p->p.pool, p->p.loop, "OSPF Vlink");
|
||||
ifa = mb_allocz(pool, sizeof(struct ospf_iface) + 16);
|
||||
ifa->oa = p->backbone;
|
||||
ifa->cf = ip;
|
||||
|
@ -80,7 +80,7 @@ struct ospf_neighbor *
|
||||
ospf_neighbor_new(struct ospf_iface *ifa)
|
||||
{
|
||||
struct ospf_proto *p = ifa->oa->po;
|
||||
struct pool *pool = rp_new(p->p.pool, "OSPF Neighbor");
|
||||
struct pool *pool = rp_new(p->p.pool, p->p.loop, "OSPF Neighbor");
|
||||
struct ospf_neighbor *n = mb_allocz(pool, sizeof(struct ospf_neighbor));
|
||||
|
||||
n->pool = pool;
|
||||
@ -120,7 +120,7 @@ ospf_neigh_down(struct ospf_neighbor *n)
|
||||
s_get(&(n->dbsi));
|
||||
release_lsrtl(p, n);
|
||||
rem_node(NODE n);
|
||||
rfree(n->pool);
|
||||
rp_free(n->pool, p->p.pool);
|
||||
|
||||
OSPF_TRACE(D_EVENTS, "Neighbor %R on %s removed", rid, ifa->ifname);
|
||||
}
|
||||
|
@ -284,7 +284,7 @@ radv_iface_new(struct radv_proto *p, struct iface *iface, struct radv_iface_conf
|
||||
|
||||
RADV_TRACE(D_EVENTS, "Adding interface %s", iface->name);
|
||||
|
||||
pool *pool = rp_new(p->p.pool, iface->name);
|
||||
pool *pool = rp_new(p->p.pool, p->p.loop, iface->name);
|
||||
ifa = mb_allocz(pool, sizeof(struct radv_iface));
|
||||
ifa->pool = pool;
|
||||
ifa->ra = p;
|
||||
@ -317,7 +317,7 @@ radv_iface_remove(struct radv_iface *ifa)
|
||||
|
||||
rem_node(NODE ifa);
|
||||
|
||||
rfree(ifa->pool);
|
||||
rp_free(ifa->pool, p->p.pool);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -596,7 +596,7 @@ rpki_check_expire_interval(uint seconds)
|
||||
static struct rpki_cache *
|
||||
rpki_init_cache(struct rpki_proto *p, struct rpki_config *cf)
|
||||
{
|
||||
pool *pool = rp_new(p->p.pool, cf->hostname);
|
||||
pool *pool = rp_new(p->p.pool, p->p.loop, cf->hostname);
|
||||
|
||||
struct rpki_cache *cache = mb_allocz(pool, sizeof(struct rpki_cache));
|
||||
|
||||
|
@ -48,6 +48,12 @@ birdloop_time_loop(struct birdloop *loop)
|
||||
return &loop->time;
|
||||
}
|
||||
|
||||
pool *
|
||||
birdloop_pool(struct birdloop *loop)
|
||||
{
|
||||
return loop->pool;
|
||||
}
|
||||
|
||||
_Bool
|
||||
birdloop_inside(struct birdloop *loop)
|
||||
{
|
||||
@ -333,31 +339,59 @@ birdloop_init(void)
|
||||
times_update();
|
||||
timers_init(&main_birdloop.time, &root_pool);
|
||||
|
||||
root_pool.loop = &main_birdloop;
|
||||
|
||||
birdloop_enter_locked(&main_birdloop);
|
||||
}
|
||||
|
||||
static void birdloop_main(void *arg);
|
||||
|
||||
void
|
||||
birdloop_free(resource *r)
|
||||
{
|
||||
struct birdloop *loop = (void *) r;
|
||||
|
||||
ASSERT_DIE(loop->links == 0);
|
||||
domain_free(loop->time.domain);
|
||||
}
|
||||
|
||||
void
|
||||
birdloop_dump(resource *r)
|
||||
{
|
||||
struct birdloop *loop = (void *) r;
|
||||
|
||||
debug("%s\n", loop->pool->name);
|
||||
}
|
||||
|
||||
struct resclass birdloop_class = {
|
||||
.name = "IO Loop",
|
||||
.size = sizeof(struct birdloop),
|
||||
.free = birdloop_free,
|
||||
.dump = birdloop_dump,
|
||||
};
|
||||
|
||||
struct birdloop *
|
||||
birdloop_new(pool *pp, uint order, const char *name)
|
||||
{
|
||||
struct domain_generic *dg = domain_new(name, order);
|
||||
|
||||
pool *p = rp_new(pp, name);
|
||||
struct birdloop *loop = mb_allocz(p, sizeof(struct birdloop));
|
||||
loop->pool = p;
|
||||
struct birdloop *loop = ralloc(pp, &birdloop_class);
|
||||
|
||||
loop->time.domain = dg;
|
||||
loop->time.loop = loop;
|
||||
|
||||
birdloop_enter(loop);
|
||||
|
||||
loop->pool = rp_new(pp, loop, name);
|
||||
loop->parent = pp;
|
||||
rmove(&loop->r, loop->pool);
|
||||
|
||||
wakeup_init(loop);
|
||||
ev_init_list(&loop->event_list, loop, name);
|
||||
timers_init(&loop->time, p);
|
||||
timers_init(&loop->time, loop->pool);
|
||||
sockets_init(loop);
|
||||
|
||||
loop->time.coro = coro_run(p, birdloop_main, loop);
|
||||
loop->time.coro = coro_run(loop->pool, birdloop_main, loop);
|
||||
|
||||
birdloop_leave(loop);
|
||||
|
||||
@ -389,14 +423,6 @@ birdloop_stop_self(struct birdloop *loop, void (*stopped)(void *data), void *dat
|
||||
birdloop_do_stop(loop, stopped, data);
|
||||
}
|
||||
|
||||
void
|
||||
birdloop_free(struct birdloop *loop)
|
||||
{
|
||||
ASSERT_DIE(loop->links == 0);
|
||||
domain_free(loop->time.domain);
|
||||
rfree(loop->pool);
|
||||
}
|
||||
|
||||
static void
|
||||
birdloop_enter_locked(struct birdloop *loop)
|
||||
{
|
||||
@ -529,7 +555,25 @@ birdloop_main(void *arg)
|
||||
ASSERT_DIE(loop->sock_num == 0);
|
||||
|
||||
birdloop_leave(loop);
|
||||
|
||||
/* Lock parent loop */
|
||||
pool *parent = loop->parent;
|
||||
birdloop_enter(parent->loop);
|
||||
|
||||
/* Move the loop temporarily to parent pool */
|
||||
birdloop_enter(loop);
|
||||
rmove(&loop->r, parent);
|
||||
birdloop_leave(loop);
|
||||
|
||||
/* Announce loop stop */
|
||||
loop->stopped(loop->stop_data);
|
||||
|
||||
/* Free the pool and loop */
|
||||
birdloop_enter(loop);
|
||||
rp_free(loop->pool, parent);
|
||||
birdloop_leave(loop);
|
||||
rfree(&loop->r);
|
||||
|
||||
/* And finally leave the parent loop before finishing */
|
||||
birdloop_leave(parent->loop);
|
||||
}
|
||||
|
||||
|
||||
|
@ -9,7 +9,10 @@
|
||||
|
||||
struct birdloop
|
||||
{
|
||||
resource r;
|
||||
|
||||
pool *pool;
|
||||
pool *parent;
|
||||
|
||||
struct timeloop time;
|
||||
event_list event_list;
|
||||
|
@ -74,7 +74,7 @@ static list krt_proto_list;
|
||||
void
|
||||
krt_io_init(void)
|
||||
{
|
||||
krt_pool = rp_new(&root_pool, "Kernel Syncer");
|
||||
krt_pool = rp_new(&root_pool, &main_birdloop, "Kernel Syncer");
|
||||
krt_filter_lp = lp_new_default(krt_pool);
|
||||
init_list(&krt_proto_list);
|
||||
krt_sys_io_init();
|
||||
|
@ -52,7 +52,7 @@ async_dump(void)
|
||||
{
|
||||
debug("INTERNAL STATE DUMP\n\n");
|
||||
|
||||
rdump(&root_pool);
|
||||
rp_dump(&root_pool);
|
||||
sk_dump_all();
|
||||
// XXXX tm_dump_all();
|
||||
if_dump_all();
|
||||
|
@ -65,8 +65,8 @@ bt_bird_init(void)
|
||||
|
||||
the_bird_lock();
|
||||
resource_init();
|
||||
olock_init();
|
||||
birdloop_init();
|
||||
olock_init();
|
||||
io_init();
|
||||
rt_init();
|
||||
if_init();
|
||||
|
Loading…
Reference in New Issue
Block a user