mirror of
https://git.rwth-aachen.de/acs/public/villas/node/
synced 2025-03-09 00:00:00 +01:00
replaced reference counters by list with references
This commit is contained in:
parent
3d325cb477
commit
0c230af5b7
12 changed files with 86 additions and 82 deletions
|
@ -67,8 +67,15 @@ void list_push(struct list *l, void *p);
|
|||
*/
|
||||
void * list_lookup(struct list *l, const char *name);
|
||||
|
||||
/** Return the first element of the list for which cmp returns zero */
|
||||
void * list_search(struct list *l, cmp_cb_t cmp, void *ctx);
|
||||
|
||||
/** Returns the number of occurences for which cmp returns zero when called on all list elements. */
|
||||
int list_count(struct list *l, cmp_cb_t cmp, void *ctx);
|
||||
|
||||
/** Return 0 if list contains pointer p */
|
||||
int list_contains(struct list *l, void *p);
|
||||
|
||||
/** Sort the list using the quicksort algorithm of libc */
|
||||
void list_sort(struct list *l, cmp_cb_t cmp);
|
||||
|
||||
|
|
|
@ -56,6 +56,8 @@ extern struct list node_types;
|
|||
struct node_type {
|
||||
/** The unique name of this node. This must be allways the first member! */
|
||||
const char *name;
|
||||
/** A list of all existing nodes of this type. */
|
||||
struct list instances;
|
||||
|
||||
enum {
|
||||
BSD_SOCKET, /**< BSD Socket API */
|
||||
|
@ -164,7 +166,6 @@ struct node
|
|||
const char *name; /**< A short identifier of the node, only used for configuration and logging */
|
||||
char *_print; /**< A string used to print to screen. */
|
||||
|
||||
int refcnt; /**< How many paths are sending / receiving from this node? */
|
||||
int combine; /**< Number of messages to send / recv at once (scatter / gather) */
|
||||
int affinity; /**< CPU Affinity of this node */
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ struct path
|
|||
struct list destinations; /**< List of all outgoing nodes */
|
||||
struct list hooks; /**< List of function pointers to hooks */
|
||||
|
||||
int enabled; /**< Is this path enabled */
|
||||
int tfd; /**< Timer file descriptor for fixed rate sending */
|
||||
double rate; /**< Send messages with a fixed rate over this path */
|
||||
|
||||
|
|
|
@ -103,7 +103,7 @@ int config_parse_path(config_setting_t *cfg,
|
|||
{
|
||||
config_setting_t *cfg_out, *cfg_hook;
|
||||
const char *in;
|
||||
int enabled, reverse;
|
||||
int reverse;
|
||||
|
||||
struct path *p = path_create();
|
||||
|
||||
|
@ -130,8 +130,8 @@ int config_parse_path(config_setting_t *cfg,
|
|||
/* Initialize hooks and their private data / parameters */
|
||||
path_run_hook(p, HOOK_INIT);
|
||||
|
||||
if (!config_setting_lookup_bool(cfg, "enabled", &enabled))
|
||||
enabled = 1;
|
||||
if (!config_setting_lookup_bool(cfg, "enabled", &p->enabled))
|
||||
p->enabled = 1;
|
||||
if (!config_setting_lookup_bool(cfg, "reverse", &reverse))
|
||||
reverse = 0;
|
||||
if (!config_setting_lookup_float(cfg, "rate", &p->rate))
|
||||
|
@ -143,52 +143,31 @@ int config_parse_path(config_setting_t *cfg,
|
|||
|
||||
p->cfg = cfg;
|
||||
|
||||
if (enabled) {
|
||||
p->in->refcnt++;
|
||||
p->in->_vt->refcnt++;
|
||||
list_push(paths, p);
|
||||
|
||||
list_foreach(struct node *node, &p->destinations) {
|
||||
node->refcnt++;
|
||||
node->_vt->refcnt++;
|
||||
}
|
||||
|
||||
list_push(paths, p);
|
||||
if (reverse) {
|
||||
if (list_length(&p->destinations) > 1)
|
||||
error("Can't reverse path with multiple destination nodes");
|
||||
|
||||
if (reverse) {
|
||||
if (list_length(&p->destinations) > 1)
|
||||
error("Can't reverse path with multiple destination nodes");
|
||||
struct path *r = path_create();
|
||||
|
||||
struct path *r = path_create();
|
||||
|
||||
/* Swap in/out */
|
||||
r->in = p->out;
|
||||
r->out = p->in;
|
||||
/* Swap in/out */
|
||||
r->in = p->out;
|
||||
r->out = p->in;
|
||||
|
||||
list_push(&r->destinations, r->out);
|
||||
list_push(&r->destinations, r->out);
|
||||
|
||||
/* Increment reference counters */
|
||||
r->in->refcnt++;
|
||||
r->in->_vt->refcnt++;
|
||||
r->out->refcnt++;
|
||||
r->out->_vt->refcnt++;
|
||||
if (cfg_hook)
|
||||
config_parse_hooklist(cfg_hook, &r->hooks);
|
||||
|
||||
if (cfg_hook)
|
||||
config_parse_hooklist(cfg_hook, &r->hooks);
|
||||
/* Initialize hooks and their private data / parameters */
|
||||
path_run_hook(r, HOOK_INIT);
|
||||
|
||||
/* Initialize hooks and their private data / parameters */
|
||||
path_run_hook(r, HOOK_INIT);
|
||||
|
||||
r->rate = p->rate;
|
||||
r->poolsize = p->poolsize;
|
||||
r->msgsize = p->msgsize;
|
||||
r->rate = p->rate;
|
||||
r->poolsize = p->poolsize;
|
||||
r->msgsize = p->msgsize;
|
||||
|
||||
list_push(paths, r);
|
||||
}
|
||||
}
|
||||
else {
|
||||
warn("Path %s is not enabled", path_print(p));
|
||||
|
||||
path_destroy(p);
|
||||
list_push(paths, r);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -72,6 +72,32 @@ void * list_lookup(struct list *l, const char *name)
|
|||
return list_search(l, cmp, (void *) name);
|
||||
}
|
||||
|
||||
int list_count(struct list *l, cmp_cb_t cmp, void *ctx)
|
||||
{
|
||||
int c = 0;
|
||||
|
||||
pthread_mutex_lock(&l->lock);
|
||||
|
||||
void *e;
|
||||
list_foreach(e, l) {
|
||||
if (!cmp(e, ctx))
|
||||
c++;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&l->lock);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
int list_contains(struct list *l, void *p)
|
||||
{
|
||||
int cmp(const void *a, const void *b) {
|
||||
return a == b;
|
||||
}
|
||||
|
||||
return list_count(l, cmp, p);
|
||||
}
|
||||
|
||||
void * list_search(struct list *l, cmp_cb_t cmp, void *ctx)
|
||||
{
|
||||
pthread_mutex_lock(&l->lock);
|
||||
|
|
|
@ -36,10 +36,14 @@ struct list node_types = LIST_INIT(NULL);
|
|||
int node_init(int argc, char *argv[], struct settings *set)
|
||||
{ INDENT
|
||||
list_foreach(const struct node_type *vt, &node_types) {
|
||||
if (vt->refcnt) {
|
||||
if (list_length(&vt->instances) > 0) {
|
||||
info("Initializing '%s' node type", vt->name);
|
||||
vt->init(argc, argv, set);
|
||||
|
||||
if (vt->init)
|
||||
vt->init(argc, argv, set);
|
||||
}
|
||||
else
|
||||
warn("No node is using the '%s' type. Skipping...", vt->name);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -49,7 +53,7 @@ int node_deinit()
|
|||
{ INDENT
|
||||
/* De-initialize node types */
|
||||
list_foreach(const struct node_type *vt, &node_types) {
|
||||
if (vt->refcnt) {
|
||||
if (list_length(&vt->instances) > 0) {
|
||||
info("De-initializing '%s' node type", vt->name);
|
||||
vt->deinit();
|
||||
}
|
||||
|
@ -60,12 +64,7 @@ int node_deinit()
|
|||
|
||||
int node_start(struct node *n)
|
||||
{ INDENT
|
||||
if (!n->refcnt) {
|
||||
warn("Node '%s' is unused. Skipping...", n->name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
debug(1, "Starting node '%s' of type '%s' (%s)", n->name, n->_vt->name, node_print(n));
|
||||
info("Starting node '%s' of type '%s' (%s)", n->name, n->_vt->name, node_print(n));
|
||||
|
||||
{ INDENT
|
||||
return node_open(n);
|
||||
|
@ -74,18 +73,11 @@ int node_start(struct node *n)
|
|||
|
||||
int node_stop(struct node *n)
|
||||
{ INDENT
|
||||
int ret;
|
||||
|
||||
if (!n->refcnt) /* Unused and not started. No reason to stop.. */
|
||||
return -1;
|
||||
|
||||
info("Stopping node '%s'", n->name);
|
||||
|
||||
{ INDENT
|
||||
ret = node_close(n);
|
||||
return node_close(n);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
char * node_print(struct node *n)
|
||||
|
@ -115,6 +107,8 @@ struct node * node_create(struct node_type *vt)
|
|||
{
|
||||
struct node *n = alloc(sizeof(struct node));
|
||||
|
||||
list_push(&vt->instances, n);
|
||||
|
||||
n->_vt = vt;
|
||||
|
||||
return n;
|
||||
|
|
|
@ -17,9 +17,6 @@
|
|||
/** Global OPAL specific settings */
|
||||
static struct opal_global *og = NULL;
|
||||
|
||||
/** List of all opal nodes */
|
||||
static struct list opals;
|
||||
|
||||
int opal_init(int argc, char *argv[], struct settings *set)
|
||||
{ INDENT
|
||||
int err;
|
||||
|
@ -142,8 +139,6 @@ int opal_parse(config_setting_t *cfg, struct node *n)
|
|||
n->opal = o;
|
||||
n->cfg = cfg;
|
||||
|
||||
list_push(&opals, o);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -101,9 +101,6 @@ int main(int argc, char *argv[])
|
|||
if (reverse)
|
||||
node_reverse(node);
|
||||
|
||||
node->refcnt++;
|
||||
node->_vt->refcnt++;
|
||||
|
||||
node_init(argc-optind, argv+optind, &set);
|
||||
node_start(node);
|
||||
|
||||
|
|
|
@ -101,9 +101,6 @@ int main(int argc, char *argv[])
|
|||
if (reverse)
|
||||
node_reverse(node);
|
||||
|
||||
node->refcnt++;
|
||||
node->_vt->refcnt++;
|
||||
|
||||
info("Initialize node types");
|
||||
node_init(argc-optind, argv+optind, &set);
|
||||
|
||||
|
|
|
@ -180,12 +180,25 @@ int main(int argc, char *argv[])
|
|||
node_init(argc, argv, &settings);
|
||||
|
||||
info("Starting nodes");
|
||||
list_foreach(struct node *n, &nodes)
|
||||
node_start(n);
|
||||
list_foreach(struct node *n, &nodes) {
|
||||
int used_by_path(struct path *p, struct node *n) {
|
||||
return (p->in == n) || list_contains(&p->destinations, n);
|
||||
}
|
||||
|
||||
int refs = list_count(&paths, (cmp_cb_t) used_by_path, n);
|
||||
if (refs)
|
||||
node_start(n);
|
||||
else
|
||||
warn("Node '%s' is unused. Skipping...", n->name);
|
||||
}
|
||||
|
||||
info("Starting paths");
|
||||
list_foreach(struct path *p, &paths)
|
||||
path_start(p);
|
||||
list_foreach(struct path *p, &paths) {
|
||||
if (p->enabled)
|
||||
path_start(p);
|
||||
else
|
||||
warn("Path %s is disabled. Skipping...", path_print(p));
|
||||
}
|
||||
|
||||
/* Run! */
|
||||
if (settings.stats > 0) {
|
||||
|
|
|
@ -35,8 +35,6 @@
|
|||
/** Linked list of interfaces */
|
||||
extern struct list interfaces;
|
||||
|
||||
/** Linked list of all sockets nodes */
|
||||
static struct list sockets;
|
||||
|
||||
int socket_init(int argc, char * argv[], struct settings *set)
|
||||
{ INDENT
|
||||
|
@ -47,7 +45,8 @@ int socket_init(int argc, char * argv[], struct settings *set)
|
|||
list_init(&interfaces, (dtor_cb_t) if_destroy);
|
||||
|
||||
/* Gather list of used network interfaces */
|
||||
list_foreach(struct socket *s, &sockets) {
|
||||
list_foreach(struct node *n, &vt.instances) {
|
||||
struct socket *s = n->socket;
|
||||
struct rtnl_link *link;
|
||||
|
||||
/* Determine outgoing interface */
|
||||
|
@ -317,8 +316,6 @@ int socket_parse(config_setting_t *cfg, struct node *n)
|
|||
|
||||
n->socket = s;
|
||||
|
||||
list_push(&sockets, s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -96,9 +96,6 @@ int main(int argc, char *argv[])
|
|||
if (!node)
|
||||
error("There's no node with the name '%s'", argv[3]);
|
||||
|
||||
node->refcnt++;
|
||||
node->_vt->refcnt++;
|
||||
|
||||
node_init(argc-3, argv+3, &settings);
|
||||
node_start(node);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue