1
0
Fork 0
mirror of https://git.rwth-aachen.de/acs/public/villas/node/ synced 2025-03-09 00:00:00 +01:00

replaced most occurrences of list_foreach with a traditional for loop due to performance reasons

This commit is contained in:
Steffen Vogel 2017-03-25 21:23:31 +01:00
parent b1fdeac63f
commit 411b9dd326
13 changed files with 162 additions and 74 deletions

View file

@ -30,12 +30,11 @@
}
#define list_length(list) ((list)->length)
#define list_at(list, index) ((list)->length > index ? (list)->array[index] : NULL)
#define list_at_safe(list, index) ((list)->length > index ? (list)->array[index] : NULL)
#define list_at(list, index) ((list)->array[index])
#define list_first(list) list_at(list, 0)
#define list_last(list) list_at(list, (list)->length-1)
#define list_foreach(ptr, list) for (int _i = 0, _p; _p = 1, _i < (list)->length; _i++) \
for (ptr = (list)->array[_i]; _p--; )
/** Callback to destroy list elements.
*

View file

@ -19,7 +19,9 @@ static int api_nodes(struct api_ressource *r, json_t *args, json_t **resp, struc
{
json_t *json_nodes = json_array();
list_foreach(struct node *n, &s->api->super_node->nodes) {
for (size_t i = 0; i < list_length(&s->api->super_node->nodes); i++) {
struct node *n = list_at(&s->api->super_node->nodes, i);
json_t *json_node = json_pack("{ s: s, s: i, s: i, s: i, s: i }",
"name", node_name_short(n),
"state", n->state,

View file

@ -59,7 +59,9 @@ int if_start(struct interface *i, int affinity)
/* Assign fwmark's to socket nodes which have netem options */
int ret, mark = 0;
list_foreach(struct socket *s, &i->sockets) {
for (size_t j = 0; j < list_length(&i->sockets); j++) {
struct socket *s = list_at(&i->sockets, j);
if (s->tc_qdisc)
s->mark = 1 + mark++;
}
@ -82,7 +84,9 @@ int if_start(struct interface *i, int affinity)
error("Failed to setup priority queuing discipline: %s", nl_geterror(ret));
/* Create netem qdisks and appropriate filter per netem node */
list_foreach(struct socket *s, &i->sockets) {
for (size_t j = 0; j < list_length(&i->sockets); j++) {
struct socket *s = list_at(&i->sockets, j);
if (s->tc_qdisc) {
ret = tc_mark(i, &s->tc_classifier, TC_HANDLE(1, s->mark), s->mark);
if (ret)

View file

@ -247,7 +247,9 @@ int vfio_dev_attach(struct vfio_dev *d, struct vfio_container *c, const char *na
struct vfio_group *g = NULL;
/* Check if group already exists */
list_foreach(struct vfio_group *h, &c->groups) {
for (size_t i = 0; i < list_length(&c->groups); i++) {
struct vfio_group *h = list_at(&c->groups, i);
if (h->index == index)
g = h;
}
@ -497,13 +499,18 @@ void vfio_dump(struct vfio_container *v)
info("VFIO Version: %u", v->version);
info("VFIO Extensions: %#x", v->extensions);
list_foreach(struct vfio_group *g, &v->groups) {
for (size_t i = 0; i < list_length(&v->groups); i++) {
struct vfio_group *g = list_at(&v->groups, i);
info("VFIO Group %u, viable=%u, container=%d", g->index,
(g->status.flags & VFIO_GROUP_FLAGS_VIABLE) > 0,
(g->status.flags & VFIO_GROUP_FLAGS_CONTAINER_SET) > 0
);
list_foreach(struct vfio_dev *d, &g->devices) { INDENT
for (size_t i = 0; i < list_length(&g->devices); i++) { INDENT
struct vfio_device *d = list_at(&g->devices, i);
info("Device %s: regions=%u, irqs=%u, flags=%#x", d->name,
d->info.num_regions,
d->info.num_irqs,

View file

@ -40,6 +40,7 @@ void list_init(struct list *l)
l->length = 0;
l->capacity = 0;
l->array = NULL;
l->state = STATE_INITIALIZED;
}
@ -49,7 +50,9 @@ int list_destroy(struct list *l, dtor_cb_t destructor, bool release)
assert(l->state != STATE_DESTROYED);
list_foreach(void *p, l) {
for (size_t i = 0; i < list_length(l); i++) {
void *p = list_at(l, i);
if (destructor)
destructor(p);
if (release)
@ -97,7 +100,7 @@ void list_remove(struct list *l, void *p)
assert(l->state == STATE_INITIALIZED);
for (int i = 0; i < l->length; i++) {
for (size_t i = 0; i < list_length(l); i++) {
if (l->array[i] == p)
removed++;
else
@ -127,7 +130,9 @@ int list_count(struct list *l, cmp_cb_t cmp, void *ctx)
assert(l->state == STATE_INITIALIZED);
list_foreach(void *e, l) {
for (size_t i = 0; i < list_length(l); i++) {
void *e = list_at(l, i);
if (cmp(e, ctx) == 0)
c++;
}
@ -145,8 +150,9 @@ void * list_search(struct list *l, cmp_cb_t cmp, void *ctx)
assert(l->state == STATE_INITIALIZED);
list_foreach(e, l) {
if (!cmp(e, ctx))
for (size_t i = 0; i < list_length(l); i++) {
e = list_at(l, i);
if (cmp(e, ctx) == 0)
goto out;
}

View file

@ -56,7 +56,10 @@ static json_t* ngsi_build_entity(struct ngsi *i, struct sample *smps[], unsigned
if (flags & NGSI_ENTITY_ATTRIBUTES) {
json_t *attributes = json_array();
list_foreach(struct ngsi_attribute *map, &i->mapping) {
for (size_t j = 0; j < list_length(&i->mapping); j++) {
struct ngsi_attribute *map = list_at(&i->mapping, j);
json_t *attribute = json_pack("{ s: s, s: s }",
"name", map->name,
"type", map->type
@ -77,7 +80,10 @@ static json_t* ngsi_build_entity(struct ngsi *i, struct sample *smps[], unsigned
if (flags & NGSI_ENTITY_METADATA) { /* Create Metadata for attribute */
json_t *metadatas = json_array();
list_foreach(struct ngsi_metadata *meta, &map->metadata) {
for (size_t i = 0; i < list_length(&map->metadata); i++) {
struct ngsi_metadata *meta = list_at(&map->metadata, i);
json_array_append_new(metadatas, json_pack("{ s: s, s: s, s: s }",
"name", meta->name,
"type", meta->type,

View file

@ -45,7 +45,8 @@ int socket_init(int argc, char *argv[], config_setting_t *cfg)
list_init(&interfaces);
/* Gather list of used network interfaces */
list_foreach(struct node *n, &p.node.instances) {
for (size_t i = 0; i < list_length(&p.node.instances); i++) {
struct node *n = list_at(&p.node.instances, i);
struct socket *s = n->_vd;
struct rtnl_link *link;
@ -58,7 +59,10 @@ int socket_init(int argc, char *argv[], config_setting_t *cfg)
/* Search of existing interface with correct ifindex */
struct interface *i;
list_foreach(i, &interfaces) {
for (size_t k = 0; k < list_length(&interfaces); k++) {
i = list_at(&interfaces, k);
if (rtnl_link_get_ifindex(i->nl_link) == rtnl_link_get_ifindex(link))
goto found;
}
@ -79,16 +83,22 @@ found: list_push(&i->sockets, s);
if (!config_setting_lookup_int(cfg, "affinity", &affinity))
affinity = -1;
list_foreach(struct interface *i, &interfaces)
for (size_t j = 0; list_length(&interfaces); j++) {
struct interface *i = list_at(&interfaces, j);
if_start(i, affinity);
}
return 0;
}
int socket_deinit()
{
list_foreach(struct interface *i, &interfaces)
for (size_t j = 0; list_length(&interfaces); j++) {
struct interface *i = list_at(&interfaces, j);
if_stop(i);
}
list_destroy(&interfaces, (dtor_cb_t) if_destroy, false);

View file

@ -288,7 +288,9 @@ int websocket_stop(struct node *n)
{
struct websocket *w = n->_vd;
list_foreach(struct websocket_connection *c, &w->connections) {
for (size_t i = 0; i < list_length(&w->connections); i++) {
struct websocket_connection *c = list_at(&w->connections, i);
c->state = WEBSOCKET_SHUTDOWN;
lws_callback_on_writable(c->wsi);
}
@ -340,11 +342,18 @@ int websocket_write(struct node *n, struct sample *smps[], unsigned cnt)
{
struct websocket *w = n->_vd;
list_foreach(struct websocket_connection *c, &w->connections)
websocket_connection_write(c, smps, cnt);
list_foreach(struct websocket_connection *c, &connections)
for (size_t i = 0; i < list_length(&w->connections); i++) {
struct websocket_connection *c = list_at(&w->connections, i);
websocket_connection_write(c, smps, cnt);
}
for (size_t i = 0; i < list_length(&connections); i++) {
struct websocket_connection *c = list_at(&connections, i);
websocket_connection_write(c, smps, cnt);
}
return cnt;
}
@ -399,7 +408,9 @@ char * websocket_print(struct node *n)
buf = strcatf(&buf, "dests=");
list_foreach(struct lws_client_connect_info *in, &w->destinations) {
for (size_t i = 0; i < list_length(&w->destinations); i++) {
struct lws_client_connect_info *in = list_at(&w->destinations, i);
buf = strcatf(&buf, "%s://%s:%d/%s",
in->ssl_connection ? "https" : "http",
in->address,

View file

@ -57,7 +57,9 @@ static void path_read(struct path *p)
stats_update(p->stats->delta, STATS_SKIPPED, recv - enqueue);
}
list_foreach(struct path_destination *pd, &p->destinations) {
for (size_t i = 0; i < list_length(&p->destinations); i++) {
struct path_destination *pd = list_at(&p->destinations, i);
enqueued = queue_push_many(&pd->queue, (void **) smps, enqueue);
if (enqueue != enqueued)
warn("Queue overrun for path %s", path_name(p));
@ -71,7 +73,9 @@ static void path_read(struct path *p)
static void path_write(struct path *p)
{
list_foreach(struct path_destination *pd, &p->destinations) {
for (size_t i = 0; i < list_length(&p->destinations); i++) {
struct path_destination *pd = list_at(&p->destinations, i);
int cnt = pd->node->vectorize;
int sent;
int tosend;
@ -217,14 +221,13 @@ int path_parse(struct path *p, config_setting_t *cfg, struct list *nodes)
p->source->node = source;
p->source->samplelen = samplelen;
list_foreach(struct node *n, &destinations) {
if (n->_vt->write == NULL)
cerror(cfg_out, "Output node '%s' is not supported as a destination.", node_name(n));
struct path_destination pd;
pd.node = n;
pd.queuelen = queuelen;
for (size_t i = 0; i < list_length(&destinations); i++) {
struct node *n = list_at(&destinations, i);
struct path_destination pd = {
.node = n,
.queuelen = p->queuelen
};
list_push(&p->destinations, memdup(&pd, sizeof(pd)));
}
@ -238,7 +241,9 @@ int path_check(struct path *p)
{
assert(p->state != STATE_DESTROYED);
list_foreach(struct node *n, &p->destinations) {
for (size_t i = 0; i < list_length(&p->destinations); i++) {
struct node *n = list_at(&p->destinations, i);
if (!n->_vt->write)
error("Destiation node '%s' is not supported as a sink for path '%s'", node_name(n), path_name(p));
}
@ -256,7 +261,9 @@ int path_init2(struct path *p)
assert(p->state == STATE_CHECKED);
/* Add internal hooks if they are not already in the list*/
list_foreach(struct plugin *q, &plugins) {
for (size_t i = 0; i < list_length(&plugins); i++) {
struct plugin *q = list_at(&plugins, i);
if (q->type == PLUGIN_TYPE_HOOK) {
struct hook h;
struct hook_type *vt = &q->hook;
@ -273,7 +280,9 @@ int path_init2(struct path *p)
list_sort(&p->hooks, hook_cmp_priority);
/* Initialize destinations */
list_foreach(struct path_destination *pd, &p->destinations) {
for (size_t i = 0; i < list_length(&p->destinations); i++) {
struct path_destination *pd = list_at(&p->destinations, i);
ret = queue_init(&pd->queue, pd->queuelen, &memtype_hugepage);
if (ret)
error("Failed to initialize queue for path");
@ -298,8 +307,9 @@ int path_start(struct path *p)
info("Starting path: %s (#hooks=%zu)", path_name(p), list_length(&p->hooks));
list_foreach(struct hook *h, &p->hooks) {
ret = hook_run(h, HOOK_PATH_START, &(struct hook_info) { .path = p });
for (size_t i = 0; i < list_length(&p->hooks); i++) {
struct hook *h = list_at(&p->hooks, i);
if (ret)
return ret;
}
@ -324,8 +334,10 @@ int path_stop(struct path *p)
pthread_cancel(p->tid);
pthread_join(p->tid, NULL);
list_foreach(struct hook *h, &p->hooks) {
ret = hook_run(h, HOOK_PATH_STOP, &(struct hook_info) { .path = p });
for (size_t i = 0; i < list_length(&p->hooks); i++) {
struct hook *h = list_at(&p->hooks, i);
ret = hook_run(h, HOOK_STOP, NULL, 0);
if (ret)
return ret;
}
@ -366,8 +378,11 @@ const char * path_name(struct path *p)
else {
strcatf(&p->_name, "%s " MAG("=>") " [", node_name_short(p->source->node));
list_foreach(struct path_destination *pd, &p->destinations)
for (size_t i = 0; i < list_length(&p->destinations); i++) {
struct path_destination *pd = list_at(&p->destinations, i);
strcatf(&p->_name, " %s", node_name_short(pd->node));
}
strcatf(&p->_name, " ]");
}
@ -377,7 +392,9 @@ const char * path_name(struct path *p)
}
int path_uses_node(struct path *p, struct node *n) {
list_foreach(struct path_destination *pd, &p->destinations) {
for (size_t i = 0; i < list_length(&p->destinations); i++) {
struct path_destination *pd = list_at(&p->destinations, i);
if (pd->node == n)
return 0;
}
@ -412,10 +429,11 @@ int path_reverse(struct path *p, struct path *r)
r->source = ps;
list_foreach(struct hook *h, &p->hooks) {
for (size_t i = 0; i < list_length(&p->hooks); i++) {
struct hook *h = list_at(&p->hooks, i);
struct hook hc;
ret = hook_init(&hc, h->_vt, p->super_node);
ret = hook_init(&hc, h->_vt, p);
if (ret)
return ret;
@ -434,12 +452,14 @@ int path_run_hooks(struct path *p, int when, struct sample *smps[], size_t cnt)
.count = cnt
};
list_foreach(struct hook *h, &p->hooks) {
ret = hook_run(h, when, &i);
if (ret)
break;
if (i.count == 0)
for (size_t i = 0; i < list_length(&p->hooks); i++) {
struct hook *h = list_at(&p->hooks, i);
ret = hook_run(h, when, smps, &cnt);
break;
}

View file

@ -69,9 +69,11 @@ int plugin_destroy(struct plugin *p)
struct plugin * plugin_lookup(enum plugin_type type, const char *name)
{
list_foreach(struct plugin *l, &plugins) {
if (l->type == type && strcmp(l->name, name) == 0)
return l;
for (size_t i = 0; i < list_length(&plugins); i++) {
struct plugin *p = list_at(&plugins, i);
if (p->type == type && strcmp(p->name, name) == 0)
return p;
}
return NULL;
@ -79,7 +81,9 @@ struct plugin * plugin_lookup(enum plugin_type type, const char *name)
void plugin_dump(enum plugin_type type)
{
list_foreach(struct plugin *p, &plugins) {
for (size_t i = 0; i < list_length(&plugins); i++) {
struct plugin *p = list_at(&plugins, i);
if (p->type == type)
printf(" - %-12s: %s\n", p->name, p->description);
}

View file

@ -131,9 +131,7 @@ int super_node_parse_uri(struct super_node *sn, const char *uri)
afclose(af);
else
fclose(f);
return super_node_parse(sn, cfg_root);
}
else { INDENT
@ -278,13 +276,17 @@ int super_node_check(struct super_node *sn)
{
int ret;
list_foreach(struct node *n, &sn->nodes) {
for (size_t i = 0; i < list_length(&sn->nodes); i++) {
struct node *n = list_at(&sn->nodes, i);
ret = node_check(n);
if (ret)
error("Invalid configuration for node %s", node_name(n));
}
list_foreach(struct path *p, &sn->paths) {
for (size_t i = 0; i < list_length(&sn->paths); i++) {
struct path *p = list_at(&sn->paths, i);
ret = path_check(p);
if (ret)
error("Invalid configuration for path %s", path_name(p));
@ -306,14 +308,16 @@ int super_node_start(struct super_node *sn)
web_start(&sn->web);
info("Start node types");
list_foreach(struct node *n, &sn->nodes) { INDENT
config_setting_t *cfg = config_root_setting(&sn->cfg);
for (size_t i = 0; i < list_length(&sn->nodes); i++) { INDENT
struct node *n = list_at(&sn->nodes, i);
node_type_start(n->_vt, sn->cli.argc, sn->cli.argv, cfg);
node_type_start(n->_vt, sn);
}
info("Starting nodes");
list_foreach(struct node *n, &sn->nodes) { INDENT
for (size_t i = 0; i < list_length(&sn->nodes); i++) { INDENT
struct node *n = list_at(&sn->nodes, i);
int refs = list_count(&sn->paths, (cmp_cb_t) path_uses_node, n);
if (refs > 0)
node_start(n);
@ -322,7 +326,9 @@ int super_node_start(struct super_node *sn)
}
info("Starting paths");
list_foreach(struct path *p, &sn->paths) { INDENT
for (size_t i = 0; i < list_length(&sn->paths); i++) { INDENT
struct path *p = list_at(&sn->paths, i);
if (p->enabled) {
path_init(p, sn);
path_start(p);
@ -341,17 +347,22 @@ int super_node_stop(struct super_node *sn)
assert(sn->state == STATE_STARTED);
info("Stopping paths");
list_foreach(struct path *p, &sn->paths) { INDENT
for (size_t i = 0; i < list_length(&sn->paths); i++) { INDENT
struct path *p = list_at(&sn->paths, i);
path_stop(p);
}
info("Stopping nodes");
list_foreach(struct node *n, &sn->nodes) { INDENT
for (size_t i = 0; i < list_length(&sn->nodes); i++) { INDENT
struct node *n = list_at(&sn->nodes, i);
node_stop(n);
}
info("De-initializing node types");
list_foreach(struct plugin *p, &plugins) { INDENT
for (size_t i = 0; i < list_length(&plugins); i++) { INDENT
struct plugin *p = list_at(&plugins, i);
if (p->type == PLUGIN_TYPE_NODE)
node_type_stop(&p->node);
}

View file

@ -107,9 +107,14 @@ int main(int argc, char *argv[])
while (1) {
now = time_now();
if (sn.stats > 0 && time_delta(&last, &now) > sn.stats) {
list_foreach(struct path *p, &sn.paths) {
list_foreach(struct hook *h, &p->hooks)
hook_run(h, HOOK_PERIODIC, NULL);
for (size_t i = 0; i < list_length(&sn.paths); i++) {
struct path *p = list_at(&sn.paths, i);
for (size_t j = 0; j < list_length(&p->hooks); j++) {
struct hook *h = list_at(&p->hooks, j);
hook_run(h, HOOK_PERIODIC, NULL, 0);
}
}
last = time_now();

View file

@ -116,15 +116,18 @@ Test(list, basics)
cr_assert_eq(list_last(&l), (void *) 99);
cr_assert_eq(list_first(&l), NULL);
i = 0;
list_foreach (void *j, &l)
cr_assert_eq(j, (void *) i++);
for (size_t j = 0, i = 0; j < list_length(&l); j++) {
void *k = list_at(&l, j);
cr_assert_eq(k, (void *) i++);
}
list_sort(&l, compare); /* Reverse list */
i = 99;
list_foreach (void *j, &l) {
cr_assert_eq(j, (void *) i, "Is %p, expected %p", i, j);
for (size_t j = 0, i = 99; j < list_length(&l); j++) {
void *k = list_at(&l, j);
cr_assert_eq(k, (void *) i, "Is %p, expected %p", i, k);
i--;
}