From 760e17f142eb5cc0f594f1383ae68bb63bebe9ee Mon Sep 17 00:00:00 2001 From: Dimitri Staessens Date: Sun, 15 Feb 2026 12:26:04 +0100 Subject: lib: Add struct llist for lists tracking len The DHT uses a struct {struct list_head, size_t len} pattern, which is also useful in the registry and other places. Having a struct llist (defined in list.h) with consistent macros for addition/deletion etc removes a lot of duplication and boilerplate and reduces the risk of inconsistent updates. The list management is now a macro-only implementation. Signed-off-by: Dimitri Staessens Signed-off-by: Sander Vrijders --- src/ipcpd/broadcast/dt.c | 60 +++-- src/ipcpd/unicast/dir/dht.c | 396 ++++++++++++++------------------- src/ipcpd/unicast/dir/tests/dht_test.c | 43 ++-- src/ipcpd/unicast/routing/graph.c | 40 ++-- src/ipcpd/unicast/routing/link-state.c | 68 +++--- src/irmd/reg/name.c | 61 ++--- src/irmd/reg/name.h | 15 +- src/irmd/reg/proc.c | 22 +- src/irmd/reg/proc.h | 3 +- src/irmd/reg/prog.c | 22 +- src/irmd/reg/prog.h | 3 +- src/irmd/reg/reg.c | 252 +++++++++------------ src/irmd/reg/tests/name_test.c | 8 +- src/irmd/reg/tests/proc_test.c | 4 +- src/irmd/reg/tests/prog_test.c | 4 +- src/irmd/reg/tests/reg_test.c | 34 +-- src/lib/CMakeLists.txt | 1 - src/lib/list.c | 78 ------- 18 files changed, 420 insertions(+), 694 deletions(-) delete mode 100644 src/lib/list.c (limited to 'src') diff --git a/src/ipcpd/broadcast/dt.c b/src/ipcpd/broadcast/dt.c index eb1a45b9..30e89a4f 100644 --- a/src/ipcpd/broadcast/dt.c +++ b/src/ipcpd/broadcast/dt.c @@ -58,14 +58,13 @@ struct nb { }; struct { - struct list_head nbs; - size_t nbs_len; - pthread_rwlock_t nbs_lock; + struct llist nbs; + pthread_rwlock_t lock; - fset_t * set; + fset_t * set; - pthread_t reader; - pthread_t listener; + pthread_t reader; + pthread_t listener; } fwd; static int dt_add_nb(int fd) @@ -73,12 +72,12 @@ static int dt_add_nb(int fd) struct list_head * p; struct nb * nb; - pthread_rwlock_wrlock(&fwd.nbs_lock); + pthread_rwlock_wrlock(&fwd.lock); - list_for_each(p, &fwd.nbs) { + llist_for_each(p, &fwd.nbs) { struct nb * el = list_entry(p, struct nb, next); if (el->fd == fd) { - pthread_rwlock_unlock(&fwd.nbs_lock); + pthread_rwlock_unlock(&fwd.lock); log_warn("Already know neighbor on fd %d.", fd); return 0; } @@ -86,18 +85,16 @@ static int dt_add_nb(int fd) nb = malloc(sizeof(*nb)); if (nb == NULL) { - pthread_rwlock_unlock(&fwd.nbs_lock); + pthread_rwlock_unlock(&fwd.lock); log_err("Failed to malloc neighbor struct."); return -ENOMEM; } nb->fd = fd; - list_add_tail(&nb->next, p); + llist_add_tail(&nb->next, &fwd.nbs); - ++fwd.nbs_len; - - pthread_rwlock_unlock(&fwd.nbs_lock); + pthread_rwlock_unlock(&fwd.lock); log_dbg("Neighbor %d added.", fd); @@ -109,21 +106,20 @@ static int dt_del_nb(int fd) struct list_head * p; struct list_head * h; - pthread_rwlock_wrlock(&fwd.nbs_lock); + pthread_rwlock_wrlock(&fwd.lock); - list_for_each_safe(p, h, &fwd.nbs) { + llist_for_each_safe(p, h, &fwd.nbs) { struct nb * nb = list_entry(p, struct nb, next); if (nb->fd == fd) { - list_del(&nb->next); - --fwd.nbs_len; - pthread_rwlock_unlock(&fwd.nbs_lock); + llist_del(&nb->next, &fwd.nbs); + pthread_rwlock_unlock(&fwd.lock); log_dbg("Neighbor %d deleted.", nb->fd); free(nb); return 0; } } - pthread_rwlock_unlock(&fwd.nbs_lock); + pthread_rwlock_unlock(&fwd.lock); log_err("Neighbor not found on fd %d.", fd); @@ -157,11 +153,11 @@ static void dt_packet(uint8_t * buf, { struct list_head * p; - pthread_rwlock_rdlock(&fwd.nbs_lock); + pthread_rwlock_rdlock(&fwd.lock); - pthread_cleanup_push(__cleanup_rwlock_unlock, &fwd.nbs_lock); + pthread_cleanup_push(__cleanup_rwlock_unlock, &fwd.lock); - list_for_each(p, &fwd.nbs) { + llist_for_each(p, &fwd.nbs) { struct nb * nb = list_entry(p, struct nb, next); if (nb->fd != in_fd) flow_write(nb->fd, buf, len); /* FIXME: avoid copy. */ @@ -252,12 +248,12 @@ int dt_init(void) strcpy(info.comp_name, DT); strcpy(info.comp_name, DT_COMP); - list_head_init(&fwd.nbs); + llist_init(&fwd.nbs); if (notifier_reg(handle_event, NULL)) goto fail_notifier_reg; - if (pthread_rwlock_init(&fwd.nbs_lock, NULL)) + if (pthread_rwlock_init(&fwd.lock, NULL)) goto fail_lock_init; fwd.set = fset_create(); @@ -273,8 +269,6 @@ int dt_init(void) if (connmgr_comp_init(COMPID_DT, &info)) goto fail_connmgr_comp_init; - fwd.nbs_len = 0; - return 0; fail_connmgr_comp_init: @@ -286,7 +280,7 @@ int dt_init(void) fail_pthread_create_reader: fset_destroy(fwd.set); fail_fset_create: - pthread_rwlock_destroy(&fwd.nbs_lock); + pthread_rwlock_destroy(&fwd.lock); fail_lock_init: notifier_unreg(handle_event); fail_notifier_reg: @@ -308,15 +302,15 @@ void dt_fini(void) fset_destroy(fwd.set); - pthread_rwlock_wrlock(&fwd.nbs_lock); + pthread_rwlock_wrlock(&fwd.lock); - list_for_each_safe(p, h, &fwd.nbs) { + llist_for_each_safe(p, h, &fwd.nbs) { struct nb * n = list_entry(p, struct nb, next); - list_del(&n->next); + llist_del(&n->next, &fwd.nbs); free(n); } - pthread_rwlock_unlock(&fwd.nbs_lock); + pthread_rwlock_unlock(&fwd.lock); - pthread_rwlock_destroy(&fwd.nbs_lock); + pthread_rwlock_destroy(&fwd.lock); } diff --git a/src/ipcpd/unicast/dir/dht.c b/src/ipcpd/unicast/dir/dht.c index c7fadcdd..bc8fb820 100644 --- a/src/ipcpd/unicast/dir/dht.c +++ b/src/ipcpd/unicast/dir/dht.c @@ -148,15 +148,8 @@ struct dht_entry { uint8_t * key; - struct { - struct list_head list; - size_t len; - } vals; /* We don't own these, only replicate */ - - struct { - struct list_head list; - size_t len; - } lvals; /* We own these, must be republished */ + struct llist vals; /* We don't own these, only replicate */ + struct llist lvals; /* We own these, must be republished */ }; struct contact { @@ -183,38 +176,24 @@ struct peer_entry { struct dht_req { struct list_head next; - uint8_t * key; - time_t t_exp; + uint8_t * key; + time_t t_exp; - struct { - struct list_head list; - size_t len; - } peers; - - struct { - struct list_head list; - size_t len; - } cache; + struct llist peers; + struct llist cache; }; struct bucket { - struct { - struct list_head list; - size_t len; - } contacts; + struct llist contacts; + struct llist alts; - struct { - struct list_head list; - size_t len; - } alts; + time_t t_refr; - time_t t_refr; + size_t depth; + uint8_t mask; - size_t depth; - uint8_t mask; - - struct bucket * parent; - struct bucket * children[1L << DHT_BETA]; + struct bucket * parent; + struct bucket * children[1L << DHT_BETA]; }; struct cmd { @@ -236,8 +215,8 @@ struct { struct { /* Kademlia parameters */ uint32_t alpha; /* Number of concurrent requests */ size_t k; /* Number of replicas to store */ - time_t t_expire; /* Expiry time for values (s) */ - time_t t_refresh; /* Refresh time for contacts (s) */ + time_t t_exp; /* Expiry time for values (s) */ + time_t t_refr; /* Refresh time for contacts (s) */ time_t t_repl; /* Replication time for values (s) */ }; @@ -261,8 +240,7 @@ struct { } contacts; struct { - struct list_head list; - size_t len; + struct llist ll; size_t vals; size_t lvals; } kv; @@ -271,10 +249,9 @@ struct { } db; struct { - struct list_head list; - size_t len; - pthread_cond_t cond; - pthread_mutex_t mtx; + struct llist ll; + pthread_cond_t cond; + pthread_mutex_t mtx; } reqs; struct { @@ -321,7 +298,7 @@ static int dht_rib_statfile(char * buf, pthread_rwlock_rdlock(&dht.db.lock); - keys = dht.db.kv.len; + keys = dht.db.kv.ll.len; lvals = dht.db.kv.lvals; vals = dht.db.kv.vals; @@ -335,7 +312,7 @@ static int dht_rib_statfile(char * buf, tmstr, ADDR_VAL32(&dht.addr), dht.alpha, dht.k, - dht.t_expire, dht.t_refresh, dht.t_repl, + dht.t_exp, dht.t_refr, dht.t_repl, keys, vals, lvals); return strlen(buf); @@ -350,14 +327,14 @@ static size_t dht_db_file_len(void) pthread_rwlock_rdlock(&dht.db.lock); - if (dht.db.kv.len == 0) { + if (llist_is_empty(&dht.db.kv.ll)) { pthread_rwlock_unlock(&dht.db.lock); sz += 14; /* No entries */ return sz; } sz += 39 * 3 + 1; /* tally + extra newline */ - sz += dht.db.kv.len * (25 + 19 + 23 + 1); + sz += dht.db.kv.ll.len * (25 + 19 + 23 + 1); vals = dht.db.kv.vals + dht.db.kv.lvals; @@ -382,7 +359,7 @@ static int dht_rib_dbfile(char * buf, pthread_rwlock_rdlock(&dht.db.lock); - if (dht.db.kv.len == 0) { + if (llist_is_empty(&dht.db.kv.ll)) { i += snprintf(buf, len, " No entries.\n"); pthread_rwlock_unlock(&dht.db.lock); return i; @@ -393,9 +370,9 @@ static int dht_rib_dbfile(char * buf, "Number of keys: %10zu\n" "Number of local values: %10zu\n" "Number of non-local values: %10zu\n\n", - dht.db.kv.len, dht.db.kv.vals, dht.db.kv.lvals); + dht.db.kv.ll.len, dht.db.kv.vals, dht.db.kv.lvals); - list_for_each(p, &dht.db.kv.list) { + llist_for_each(p, &dht.db.kv.ll) { struct dht_entry * e = list_entry(p, struct dht_entry, next); struct list_head * h; @@ -403,7 +380,7 @@ static int dht_rib_dbfile(char * buf, KEY_VAL(e->key)); i += snprintf(buf + i, len - i, " Local entries:\n"); - list_for_each(h, &e->vals.list) { + llist_for_each(h, &e->vals) { struct val_entry * v; v = list_entry(h, struct val_entry, next); @@ -416,7 +393,7 @@ static int dht_rib_dbfile(char * buf, i += snprintf(buf + i, len - i, " " VAL_FMT - ", t_replicated=%.*s, t_expire=%.*s\n", + ", t_replicated=%.*s, t_exp=%.*s\n", VAL_VAL(v->val), RIB_TM_STRLEN, tmstr, RIB_TM_STRLEN, exstr); @@ -426,7 +403,7 @@ static int dht_rib_dbfile(char * buf, i += snprintf(buf + i, len - i, " Non-local entries:\n"); - list_for_each(h, &e->lvals.list) { + llist_for_each(h, &e->lvals) { struct val_entry * v; v= list_entry(h, struct val_entry, next); @@ -439,7 +416,7 @@ static int dht_rib_dbfile(char * buf, i += snprintf(buf + i, len - i, " " VAL_FMT - ", t_replicated=%.*s, t_expire=%.*s\n", + ", t_replicated=%.*s, t_exp=%.*s\n", VAL_VAL(v->val), RIB_TM_STRLEN, tmstr, RIB_TM_STRLEN, exstr); @@ -694,11 +671,8 @@ static struct dht_entry * dht_entry_create(const uint8_t * key) goto fail_entry; list_head_init(&e->next); - list_head_init(&e->vals.list); - list_head_init(&e->lvals.list); - - e->vals.len = 0; - e->lvals.len = 0; + llist_init(&e->vals); + llist_init(&e->lvals); e->key = dht_dup_key(key); if (e->key == NULL) @@ -718,25 +692,23 @@ static void dht_entry_destroy(struct dht_entry * e) assert(e != NULL); - list_for_each_safe(p, h, &e->vals.list) { + llist_for_each_safe(p, h, &e->vals) { struct val_entry * v = list_entry(p, struct val_entry, next); - list_del(&v->next); + llist_del(&v->next, &e->vals); val_entry_destroy(v); - --e->vals.len; --dht.db.kv.vals; } - list_for_each_safe(p, h, &e->lvals.list) { + llist_for_each_safe(p, h, &e->lvals) { struct val_entry * v = list_entry(p, struct val_entry, next); - list_del(&v->next); + llist_del(&v->next, &e->lvals); val_entry_destroy(v); - --e->lvals.len; --dht.db.kv.lvals; } free(e->key); - assert(e->vals.len == 0 && e->lvals.len == 0); + assert(llist_is_empty(&e->vals) && llist_is_empty(&e->lvals)); free(e); } @@ -750,7 +722,7 @@ static struct val_entry * dht_entry_get_lval(const struct dht_entry * e, assert(val.data != NULL); assert(val.len > 0); - list_for_each(p, &e->lvals.list) { + llist_for_each(p, &e->lvals) { struct val_entry * v = list_entry(p, struct val_entry, next); if (bufcmp(&v->val, &val) == 0) return v; @@ -768,7 +740,7 @@ static struct val_entry * dht_entry_get_val(const struct dht_entry * e, assert(val.data != NULL); assert(val.len > 0); - list_for_each(p, &e->vals.list) { + llist_for_each(p, &e->vals) { struct val_entry * v = list_entry(p, struct val_entry, next); if (bufcmp(&v->val, &val) == 0) return v; @@ -805,8 +777,7 @@ static int dht_entry_update_val(struct dht_entry * e, if (v == NULL) return -ENOMEM; - list_add_tail(&v->next, &e->vals.list); - ++e->vals.len; + llist_add_tail(&v->next, &e->vals); ++dht.db.kv.vals; return 0; @@ -833,12 +804,11 @@ static int dht_entry_update_lval(struct dht_entry * e, v = dht_entry_get_lval(e, val); if (v == NULL) { log_dbg(KV_FMT " Adding lval.", KV_VAL(e->key, val)); - v = val_entry_create(val, now.tv_sec + dht.t_expire); + v = val_entry_create(val, now.tv_sec + dht.t_exp); if (v == NULL) return -ENOMEM; - list_add_tail(&v->next, &e->lvals.list); - ++e->lvals.len; + llist_add_tail(&v->next, &e->lvals); ++dht.db.kv.lvals; return 0; @@ -862,9 +832,8 @@ static int dht_entry_remove_lval(struct dht_entry * e, log_dbg(KV_FMT " Removing lval.", KV_VAL(e->key, val)); - list_del(&v->next); + llist_del(&v->next, &e->lvals); val_entry_destroy(v); - --e->lvals.len; --dht.db.kv.lvals; return 0; @@ -881,15 +850,14 @@ static void dht_entry_remove_expired_vals(struct dht_entry * e) clock_gettime(CLOCK_REALTIME_COARSE, &now); - list_for_each_safe(p, h, &e->vals.list) { + llist_for_each_safe(p, h, &e->vals) { struct val_entry * v = list_entry(p, struct val_entry, next); if (!IS_EXPIRED(v, &now)) continue; log_dbg(KV_FMT " Value expired." , KV_VAL(e->key, v->val)); - list_del(&v->next); + llist_del(&v->next, &e->vals); val_entry_destroy(v); - --e->vals.len; --dht.db.kv.vals; } } @@ -900,7 +868,7 @@ static struct dht_entry * __dht_kv_find_entry(const uint8_t * key) assert(key != NULL); - list_for_each(p, &dht.db.kv.list) { + llist_for_each(p, &dht.db.kv.ll) { struct dht_entry * e = list_entry(p, struct dht_entry, next); if (!memcmp(key, e->key, dht.id.len)) return e; @@ -919,16 +887,15 @@ static void dht_kv_remove_expired_entries(void) pthread_rwlock_wrlock(&dht.db.lock); - list_for_each_safe(p, h, &dht.db.kv.list) { + llist_for_each_safe(p, h, &dht.db.kv.ll) { struct dht_entry * e = list_entry(p, struct dht_entry, next); dht_entry_remove_expired_vals(e); if (e->lvals.len > 0 || e->vals.len > 0) continue; log_dbg(KEY_FMT " Entry removed. ", KEY_VAL(e->key)); - list_del(&e->next); + llist_del(&e->next, &dht.db.kv.ll); dht_entry_destroy(e); - --dht.db.kv.len; } pthread_rwlock_unlock(&dht.db.lock); @@ -987,15 +954,13 @@ static struct dht_req * dht_req_create(const uint8_t * key) req->t_exp = now.tv_sec + DHT_T_RESP; - list_head_init(&req->peers.list); - req->peers.len = 0; + llist_init(&req->peers); req->key = dht_dup_key(key); if (req->key == NULL) goto fail_dup_key; - list_head_init(&req->cache.list); - req->cache.len = 0; + llist_init(&req->cache); return req; @@ -1013,34 +978,32 @@ static void dht_req_destroy(struct dht_req * req) assert(req); assert(req->key); - list_for_each_safe(p, h, &req->peers.list) { + llist_for_each_safe(p, h, &req->peers) { struct peer_entry * e = list_entry(p, struct peer_entry, next); - list_del(&e->next); + llist_del(&e->next, &req->peers); free(e->id); free(e); - --req->peers.len; } - list_for_each_safe(p, h, &req->cache.list) { + llist_for_each_safe(p, h, &req->cache) { struct val_entry * e = list_entry(p, struct val_entry, next); - list_del(&e->next); + llist_del(&e->next, &req->cache); val_entry_destroy(e); - --req->cache.len; } free(req->key); - assert(req->peers.len == 0); + assert(llist_is_empty(&req->peers)); free(req); } -static struct peer_entry * dht_req_get_peer(struct dht_req * req, - struct peer_entry * e) +static struct peer_entry * dht_req_get_peer(struct dht_req * req, + const struct peer_entry * e) { struct list_head * p; - list_for_each(p, &req->peers.list) { + llist_for_each(p, &req->peers) { struct peer_entry * x = list_entry(p, struct peer_entry, next); if (x->addr == e->addr) return x; @@ -1050,8 +1013,8 @@ static struct peer_entry * dht_req_get_peer(struct dht_req * req, } #define IS_MAGIC(peer) ((peer)->cookie == dht.magic) -void dht_req_add_peer(struct dht_req * req, - struct peer_entry * e) +static int dht_req_add_peer(struct dht_req * req, + const struct peer_entry * e) { struct peer_entry * x; /* existing */ struct list_head * p; /* iterator */ @@ -1063,16 +1026,17 @@ void dht_req_add_peer(struct dht_req * req, /* * Dedupe messages to the same peer, unless - * 1) The previous request was FIND_NODE and now it's FIND_VALUE - * 2) We urgently need contacts from emergency peer (magic cookie) + * 1) The previous was FIND_NODE and now it's FIND_VALUE + * 2) We urgently need contacts (magic cookie) */ x = dht_req_get_peer(req, e); if (x != NULL && x->code >= e->code && !IS_MAGIC(e)) - goto skip; + return -1; /* Find how this contact ranks in distance to the key */ - list_for_each(p, &req->peers.list) { - struct peer_entry * y = list_entry(p, struct peer_entry, next); + llist_for_each(p, &req->peers) { + struct peer_entry * y; + y = list_entry(p, struct peer_entry, next); if (IS_CLOSER(y->id, e->id)) { pos++; continue; @@ -1080,36 +1044,32 @@ void dht_req_add_peer(struct dht_req * req, break; } - /* Add a new peer to this request if we need to */ - if (pos < dht.alpha || !IS_MAGIC(e)) { - x = malloc(sizeof(*x)); - if (x == NULL) { - log_err("Failed to malloc peer entry."); - goto skip; - } + if (pos >= dht.alpha && IS_MAGIC(e)) + return -1; - x->cookie = e->cookie; - x->addr = e->addr; - x->code = e->code; - x->t_sent = e->t_sent; - x->id = dht_dup_key(e->id); - if (x->id == NULL) { - log_err("Failed to dup peer ID."); - free(x); - goto skip; - } + x = malloc(sizeof(*x)); + if (x == NULL) { + log_err("Failed to malloc peer entry."); + return -1; + } - if (IS_MAGIC(e)) - list_add(&x->next, p); - else - list_add_tail(&x->next, p); - ++req->peers.len; - return; + x->cookie = e->cookie; + x->addr = e->addr; + x->code = e->code; + x->t_sent = e->t_sent; + x->id = dht_dup_key(e->id); + if (x->id == NULL) { + log_err("Failed to dup peer ID."); + free(x); + return -1; } - skip: - list_del(&e->next); - free(e->id); - free(e); + + if (IS_MAGIC(e)) + llist_add_at(&x->next, p, &req->peers); + else + llist_add_tail_at(&x->next, p, &req->peers); + + return 0; } static size_t dht_req_add_peers(struct dht_req * req, @@ -1123,8 +1083,13 @@ static size_t dht_req_add_peers(struct dht_req * req, assert(pl != NULL); list_for_each_safe(p, h, pl) { - struct peer_entry * e = list_entry(p, struct peer_entry, next); - dht_req_add_peer(req, e); + struct peer_entry * e; + e = list_entry(p, struct peer_entry, next); + if (dht_req_add_peer(req, e) < 0) { + list_del(&e->next); + free(e->id); + free(e); + } } return n; @@ -1137,7 +1102,7 @@ static bool dht_req_has_peer(struct dht_req * req, assert(req != NULL); - list_for_each(p, &req->peers.list) { + llist_for_each(p, &req->peers) { struct peer_entry * e = list_entry(p, struct peer_entry, next); if (e->cookie == cookie) return true; @@ -1209,7 +1174,7 @@ static struct dht_req * __dht_kv_req_get_req(const uint8_t * key) { struct list_head * p; - list_for_each(p, &dht.reqs.list) { + llist_for_each(p, &dht.reqs.ll) { struct dht_req * r = list_entry(p, struct dht_req, next); if (memcmp(r->key, key, dht.id.len) == 0) return r; @@ -1228,7 +1193,7 @@ static struct dht_req * __dht_kv_get_req_cache(const uint8_t * key) if (req == NULL) return NULL; - if (req->cache.len == 0) + if (llist_is_empty(&req->cache)) return NULL; return req; @@ -1244,8 +1209,7 @@ static void __dht_kv_req_remove(const uint8_t * key) if (req == NULL) return; - list_del(&req->next); - --dht.reqs.len; + llist_del(&req->next, &dht.reqs.ll); dht_req_destroy(req); } @@ -1301,9 +1265,9 @@ static int dht_kv_update_req(const uint8_t * key, req = __dht_kv_req_get_req(key); if (req == NULL) { - if (dht.reqs.len == DHT_MAX_REQS) { + if (dht.reqs.ll.len == DHT_MAX_REQS) { log_err(KEY_FMT " Max reqs reached (%zu).", - KEY_VAL(key), dht.reqs.len); + KEY_VAL(key), dht.reqs.ll.len); peer_list_destroy(pl); goto fail_req; } @@ -1312,8 +1276,7 @@ static int dht_kv_update_req(const uint8_t * key, log_err(KEY_FMT "Failed to create req.", KEY_VAL(key)); goto fail_req; } - list_add_tail(&req->next, &dht.reqs.list); - ++dht.reqs.len; + llist_add_tail(&req->next, &dht.reqs.ll); } if (req->cache.len > 0) /* Already have values */ @@ -1322,9 +1285,9 @@ static int dht_kv_update_req(const uint8_t * key, dht_req_add_peers(req, pl); req->t_exp = now.tv_sec + DHT_T_RESP; - if (dht.reqs.len > DHT_WARN_REQS) { + if (dht.reqs.ll.len > DHT_WARN_REQS) { log_warn("Number of outstanding requests (%zu) exceeds %u.", - dht.reqs.len, DHT_WARN_REQS); + dht.reqs.ll.len, DHT_WARN_REQS); } pthread_mutex_unlock(&dht.reqs.mtx); @@ -1368,8 +1331,7 @@ static int dht_kv_respond_req(uint8_t * key, continue; } - list_add_tail(&e->next, &req->cache.list); - ++req->cache.len; + llist_add_tail(&e->next, &req->cache); } pthread_cond_broadcast(&dht.reqs.cond); @@ -1434,7 +1396,7 @@ static ssize_t dht_kv_wait_req(const uint8_t * key, memset(*vals, 0, max * sizeof(**vals)); - list_for_each(p, &req->cache.list) { + llist_for_each(p, &req->cache) { struct val_entry * v; if (i == max) break; /* We have enough values */ @@ -1535,10 +1497,10 @@ static ssize_t dht_kv_contact_list(const uint8_t * key, goto fail_bucket; } - b->t_refr = t.tv_sec + dht.t_refresh; + b->t_refr = t.tv_sec + dht.t_refr; if (b->contacts.len == dht.k || b->parent == NULL) { - list_for_each(p, &b->contacts.list) { + llist_for_each(p, &b->contacts) { struct contact * c; struct contact * d; c = list_entry(p, struct contact, next); @@ -1554,7 +1516,7 @@ static ssize_t dht_kv_contact_list(const uint8_t * key, } else { struct bucket * d = b->parent; for (i = 0; i < (1L << DHT_BETA) && len < dht.k; ++i) { - list_for_each(p, &d->children[i]->contacts.list) { + llist_for_each(p, &d->children[i]->contacts) { struct contact * c; struct contact * d; c = list_entry(p, struct contact, next); @@ -1661,11 +1623,11 @@ static void __dht_kv_bucket_refresh_list(struct bucket * b, __dht_kv_bucket_refresh_list(b->children[i], t, r); } - if (b->contacts.len == 0) + if (llist_is_empty(&b->contacts)) return; - c = list_first_entry(&b->contacts.list, struct contact, next); - if (t > c->t_seen + dht.t_refresh) { + c = llist_first_entry(&b->contacts, struct contact, next); + if (t > c->t_seen + dht.t_refr) { d = contact_create(c->id, c->addr); if (d != NULL) list_add(&d->next, r); @@ -1682,14 +1644,12 @@ static struct bucket * bucket_create(void) if (b == NULL) return NULL; - list_head_init(&b->contacts.list); - b->contacts.len = 0; + llist_init(&b->contacts); - list_head_init(&b->alts.list); - b->alts.len = 0; + llist_init(&b->alts); clock_gettime(CLOCK_REALTIME_COARSE, &t); - b->t_refr = t.tv_sec + dht.t_refresh; + b->t_refr = t.tv_sec + dht.t_refr; for (i = 0; i < (1L << DHT_BETA); ++i) b->children[i] = NULL; @@ -1713,18 +1673,16 @@ static void bucket_destroy(struct bucket * b) if (b->children[i] != NULL) bucket_destroy(b->children[i]); - list_for_each_safe(p, h, &b->contacts.list) { + llist_for_each_safe(p, h, &b->contacts) { struct contact * c = list_entry(p, struct contact, next); - list_del(&c->next); + llist_del(&c->next, &b->contacts); contact_destroy(c); - --b->contacts.len; } - list_for_each_safe(p, h, &b->alts.list) { + llist_for_each_safe(p, h, &b->alts) { struct contact * c = list_entry(p, struct contact, next); - list_del(&c->next); + llist_del(&c->next, &b->alts); contact_destroy(c); - --b->alts.len; } free(b); @@ -1759,13 +1717,11 @@ static int move_contacts(struct bucket * b, assert(b != NULL); assert(c != NULL); - list_for_each_safe(p, h, &b->contacts.list) { + llist_for_each_safe(p, h, &b->contacts) { d = list_entry(p, struct contact, next); if (bucket_has_id(c, d->id)) { - list_del(&d->next); - --b->contacts.len; - list_add_tail(&d->next, &c->contacts.list); - ++c->contacts.len; + llist_del(&d->next, &b->contacts); + llist_add_tail(&d->next, &c->contacts); } } @@ -1779,8 +1735,8 @@ static int split_bucket(struct bucket * b) size_t b_len; assert(b); - assert(b->alts.len == 0); - assert(b->contacts.len != 0); + assert(llist_is_empty(&b->alts)); + assert(!llist_is_empty(&b->contacts)); assert(b->children[0] == NULL); b_len = b->contacts.len; @@ -1836,39 +1792,33 @@ static int dht_kv_update_contacts(const uint8_t * id, goto fail_update; } - list_for_each_safe(p, h, &b->contacts.list) { + llist_for_each_safe(p, h, &b->contacts) { struct contact * d = list_entry(p, struct contact, next); if (d->addr == addr) { - list_del(&d->next); + llist_del(&d->next, &b->contacts); contact_destroy(d); - --b->contacts.len; } } if (b->contacts.len == dht.k) { if (bucket_has_id(b, dht.id.data)) { - list_add_tail(&c->next, &b->contacts.list); - ++b->contacts.len; + llist_add_tail(&c->next, &b->contacts); if (split_bucket(b)) { - list_del(&c->next); + llist_del(&c->next, &b->contacts); contact_destroy(c); - --b->contacts.len; } } else if (b->alts.len == dht.k) { struct contact * d; - d = list_first_entry(&b->alts.list, + d = llist_first_entry(&b->alts, struct contact, next); - list_del(&d->next); + llist_del(&d->next, &b->alts); contact_destroy(d); - list_add_tail(&c->next, &b->alts.list); - ++b->alts.len; + llist_add_tail(&c->next, &b->alts); } else { - list_add_tail(&c->next, &b->alts.list); - ++b->alts.len; + llist_add_tail(&c->next, &b->alts); } } else { - list_add_tail(&c->next, &b->contacts.list); - ++b->contacts.len; + llist_add_tail(&c->next, &b->contacts); } pthread_rwlock_unlock(&dht.db.lock); @@ -2116,7 +2066,7 @@ static ssize_t dht_kv_retrieve(const uint8_t * key, i = 0; - list_for_each(p, &e->vals.list) { + llist_for_each(p, &e->vals) { struct val_entry * v; if (i == n) break; /* We have enough values */ @@ -2129,7 +2079,7 @@ static ssize_t dht_kv_retrieve(const uint8_t * key, memcpy((*vals)[i++].data, v->val.data, v->val.len); } - list_for_each(p, &e->lvals.list) { + llist_for_each(p, &e->lvals) { struct val_entry * v; if (i == n) break; /* We have enough values */ @@ -2584,15 +2534,14 @@ static void __add_dht_kv_entry(struct dht_entry * e) assert(e != NULL); - list_for_each(p, &dht.db.kv.list) { + llist_for_each(p, &dht.db.kv.ll) { struct dht_entry * d = list_entry(p, struct dht_entry, next); if (IS_CLOSER(d->key, e->key)) continue; break; } - list_add_tail(&e->next, p); - ++dht.db.kv.len; + llist_add_tail_at(&e->next, p, &dht.db.kv.ll); } /* incoming store message */ @@ -2629,9 +2578,8 @@ static int dht_kv_store(const uint8_t * key, return 0; fail_add: if (new) { - list_del(&e->next); + llist_del(&e->next, &dht.db.kv.ll); dht_entry_destroy(e); - --dht.db.kv.len; } fail: pthread_rwlock_unlock(&dht.db.lock); @@ -2669,14 +2617,13 @@ static int dht_kv_publish(const uint8_t * key, pthread_rwlock_unlock(&dht.db.lock); - dht_kv_store_remote(key, val, now.tv_sec + dht.t_expire); + dht_kv_store_remote(key, val, now.tv_sec + dht.t_exp); return 0; fail_add: if (new) { - list_del(&e->next); + llist_del(&e->next, &dht.db.kv.ll); dht_entry_destroy(e); - --dht.db.kv.len; } fail: pthread_rwlock_unlock(&dht.db.lock); @@ -3451,15 +3398,14 @@ static void dht_kv_remove_expired_reqs(void) pthread_mutex_lock(&dht.reqs.mtx); - list_for_each_safe(p, h, &dht.reqs.list) { + llist_for_each_safe(p, h, &dht.reqs.ll) { struct dht_req * e; e = list_entry(p, struct dht_req, next); if (IS_EXPIRED(e, &now)) { log_dbg(KEY_FMT " Removing expired request.", KEY_VAL(e->key)); - list_del(&e->next); + llist_del(&e->next, &dht.reqs.ll); dht_req_destroy(e); - --dht.reqs.len; } } @@ -3491,7 +3437,7 @@ static void dht_entry_get_repl_lists(const struct dht_entry * e, struct list_head * p; struct val_entry * n; - list_for_each(p, &e->vals.list) { + llist_for_each(p, &e->vals) { struct val_entry * v = list_entry(p, struct val_entry, next); if (MUST_REPLICATE(v, now) && !IS_EXPIRED(v, now)) { n = val_entry_create(v->val, v->t_exp); @@ -3502,11 +3448,11 @@ static void dht_entry_get_repl_lists(const struct dht_entry * e, } } - list_for_each(p, &e->lvals.list) { + llist_for_each(p, &e->lvals) { struct val_entry * v = list_entry(p, struct val_entry, next); if (MUST_REPLICATE(v, now) && MUST_REPUBLISH(v, now)) { /* Add expire time here, to allow creating val_entry */ - n = val_entry_create(v->val, now->tv_sec + dht.t_expire); + n = val_entry_create(v->val, now->tv_sec + dht.t_exp); if (n == NULL) continue; @@ -3535,10 +3481,10 @@ static int dht_kv_next_values(uint8_t * key, pthread_rwlock_rdlock(&dht.db.lock); - if (dht.db.kv.len == 0) + if (llist_is_empty(&dht.db.kv.ll)) goto no_entries; - list_for_each_safe(p, h, &dht.db.kv.list) { + llist_for_each_safe(p, h, &dht.db.kv.ll) { e = list_entry(p, struct dht_entry, next); if (IS_CLOSER(e->key, key)) continue; /* Already processed */ @@ -3580,7 +3526,7 @@ static void dht_kv_republish_value(const uint8_t * key, assert(MUST_REPLICATE(v, now)); if (MUST_REPUBLISH(v, now)) - assert(v->t_exp >= now->tv_sec + dht.t_expire); + assert(v->t_exp >= now->tv_sec + dht.t_exp); if (dht_kv_store_remote(key, v->val, v->t_exp) == 0) { log_dbg(KV_FMT " Republished.", KV_VAL(key, v->val)); @@ -3788,8 +3734,8 @@ static void * work(void * o) nanosleep(&now, NULL); } - intv = gcd(dht.t_expire, (dht.t_expire - DHT_N_REPUB * dht.t_repl)); - intv = gcd(intv, gcd(dht.t_repl, dht.t_refresh)) / 2; + intv = gcd(dht.t_exp, (dht.t_exp - DHT_N_REPUB * dht.t_repl)); + intv = gcd(intv, gcd(dht.t_repl, dht.t_refr)) / 2; intv = MAX(1, intv / n); log_dbg("DHT worker starting %ld seconds interval.", intv * n); @@ -3870,13 +3816,13 @@ int dht_init(struct dir_dht_config * conf) dht.id.len = DHT_TEST_KEY_LEN; dht.addr = DHT_TEST_ADDR; #endif - dht.t0 = now.tv_sec; - dht.alpha = conf->params.alpha; - dht.k = conf->params.k; - dht.t_expire = conf->params.t_expire; - dht.t_refresh = conf->params.t_refresh; - dht.t_repl = conf->params.t_replicate; - dht.peer = conf->peer; + dht.t0 = now.tv_sec; + dht.alpha = conf->params.alpha; + dht.k = conf->params.k; + dht.t_exp = conf->params.t_expire; + dht.t_refr = conf->params.t_refresh; + dht.t_repl = conf->params.t_replicate; + dht.peer = conf->peer; dht.magic = generate_cookie(); @@ -3901,8 +3847,7 @@ int dht_init(struct dir_dht_config * conf) goto fail_cmds_cond; } - list_head_init(&dht.reqs.list); - dht.reqs.len = 0; + llist_init(&dht.reqs.ll); if (pthread_mutex_init(&dht.reqs.mtx, NULL)) { log_err("Failed to initialize request mutex."); @@ -3924,8 +3869,7 @@ int dht_init(struct dir_dht_config * conf) goto fail_reqs_cond; } - list_head_init(&dht.db.kv.list); - dht.db.kv.len = 0; + llist_init(&dht.db.kv.ll); dht.db.kv.vals = 0; dht.db.kv.lvals = 0; @@ -3962,9 +3906,9 @@ int dht_init(struct dir_dht_config * conf) log_dbg(" address: " ADDR_FMT32 ".", ADDR_VAL32(&dht.addr)); log_dbg(" peer: " ADDR_FMT32 ".", ADDR_VAL32(&dht.peer)); log_dbg(" magic cookie: " HASH_FMT64 ".", HASH_VAL64(&dht.magic)); - log_info(" parameters: alpha=%u, k=%zu, t_expire=%ld, " - "t_refresh=%ld, t_replicate=%ld.", - dht.alpha, dht.k, dht.t_expire, dht.t_refresh, dht.t_repl); + log_info(" parameters: alpha=%u, k=%zu, t_exp=%ld, " + "t_refr=%ld, t_replicate=%ld.", + dht.alpha, dht.k, dht.t_exp, dht.t_refr, dht.t_repl); #endif dht.state = DHT_INIT; @@ -4017,11 +3961,10 @@ void dht_fini(void) pthread_mutex_lock(&dht.reqs.mtx); - list_for_each_safe(p, h, &dht.reqs.list) { + llist_for_each_safe(p, h, &dht.reqs.ll) { struct dht_req * r = list_entry(p, struct dht_req, next); - list_del(&r->next); + llist_del(&r->next, &dht.reqs.ll); dht_req_destroy(r); - dht.reqs.len--; } pthread_mutex_unlock(&dht.reqs.mtx); @@ -4031,11 +3974,10 @@ void dht_fini(void) pthread_rwlock_wrlock(&dht.db.lock); - list_for_each_safe(p, h, &dht.db.kv.list) { + llist_for_each_safe(p, h, &dht.db.kv.ll) { struct dht_entry * e = list_entry(p, struct dht_entry, next); - list_del(&e->next); + llist_del(&e->next, &dht.db.kv.ll); dht_entry_destroy(e); - dht.db.kv.len--; } if (dht.db.contacts.root != NULL) @@ -4045,10 +3987,10 @@ void dht_fini(void) pthread_rwlock_destroy(&dht.db.lock); - assert(dht.db.kv.len == 0); + assert(llist_is_empty(&dht.db.kv.ll)); assert(dht.db.kv.vals == 0); assert(dht.db.kv.lvals == 0); - assert(dht.reqs.len == 0); + assert(llist_is_empty(&dht.reqs.ll)); freebuf(dht.id); } diff --git a/src/ipcpd/unicast/dir/tests/dht_test.c b/src/ipcpd/unicast/dir/tests/dht_test.c index 70699563..1f7026b3 100644 --- a/src/ipcpd/unicast/dir/tests/dht_test.c +++ b/src/ipcpd/unicast/dir/tests/dht_test.c @@ -46,10 +46,9 @@ /* forward declare for use in the dht code */ /* Packet sink for DHT tests */ struct { - bool enabled; + bool enabled; - struct list_head list; - size_t len; + struct llist msgs; } sink; struct message { @@ -66,8 +65,6 @@ static int sink_send_msg(buffer_t * pkt, assert(pkt != NULL); assert(addr != 0); - assert(!list_is_empty(&sink.list) || sink.len == 0); - if (!sink.enabled) goto finish; @@ -83,9 +80,8 @@ static int sink_send_msg(buffer_t * pkt, m->dst = addr; - list_add_tail(&m->next, &sink.list); + llist_add_tail(&m->next, &sink.msgs); - ++sink.len; finish: freebuf(*pkt); @@ -103,8 +99,7 @@ static int sink_send_msg(buffer_t * pkt, static void sink_init(void) { - list_head_init(&sink.list); - sink.len = 0; + llist_init(&sink.msgs); sink.enabled = true; } @@ -113,22 +108,20 @@ static void sink_clear(void) struct list_head * p; struct list_head * h; - list_for_each_safe(p, h, &sink.list) { + llist_for_each_safe(p, h, &sink.msgs) { struct message * m = list_entry(p, struct message, next); - list_del(&m->next); + llist_del(&m->next, &sink.msgs); dht_msg__free_unpacked((dht_msg_t *) m->msg, NULL); free(m); - --sink.len; } - assert(list_is_empty(&sink.list)); + assert(llist_is_empty(&sink.msgs)); } static void sink_fini(void) { sink_clear(); - - assert(list_is_empty(&sink.list) || sink.len != 0); + sink.enabled = false; } static dht_msg_t * sink_read(void) @@ -136,16 +129,12 @@ static dht_msg_t * sink_read(void) struct message * m; dht_msg_t * msg; - assert(!list_is_empty(&sink.list) || sink.len == 0); - - if (list_is_empty(&sink.list)) + if (llist_is_empty(&sink.msgs)) return NULL; - m = list_first_entry(&sink.list, struct message, next); - - --sink.len; + m = llist_first_entry(&sink.msgs, struct message, next); - list_del(&m->next); + llist_del(&m->next, &sink.msgs); msg = m->msg; @@ -978,7 +967,7 @@ static int test_dht_kv_find_node_rsp_msg_contacts(void) } if ((size_t) n < dht.k) { - printf("Failed to get enough contacts (%zu < %zu).\n", n, dht.k); + printf("Failed to get all contacts (%zu < %zu).\n", n, dht.k); goto fail_fill; } @@ -1204,7 +1193,7 @@ static int test_dht_kv_find_value_rsp_msg_contacts(void) } if ((size_t) n < dht.k) { - printf("Failed to get enough contacts (%zu < %zu).\n", n, dht.k); + printf("Failed to get all contacts (%zu < %zu).\n", n, dht.k); goto fail_fill; } @@ -1591,7 +1580,7 @@ static int test_dht_reg_unreg(void) goto fail_reg; } - if (sink.len != 0) { + if (!llist_is_empty(&sink.msgs)) { printf("Packet sent without contacts!"); goto fail_msg; } @@ -1642,7 +1631,7 @@ static int test_dht_reg_unreg_contacts(void) goto fail_reg; } - if (sink.len != dht.alpha) { + if (sink.msgs.len != dht.alpha) { printf("Packet sent to too few contacts!\n"); goto fail_msg; } @@ -1784,7 +1773,7 @@ static int test_dht_query(void) goto fail_get; } - if (sink.len != 0) { + if (!llist_is_empty(&sink.msgs)) { printf("Packet sent without contacts!"); goto fail_test; } diff --git a/src/ipcpd/unicast/routing/graph.c b/src/ipcpd/unicast/routing/graph.c index a50160b8..13939915 100644 --- a/src/ipcpd/unicast/routing/graph.c +++ b/src/ipcpd/unicast/routing/graph.c @@ -57,10 +57,7 @@ struct edge { }; struct graph { - struct { - struct list_head list; - size_t len; - } vertices; + struct llist vertices; pthread_mutex_t lock; }; @@ -88,7 +85,7 @@ static struct vertex * find_vertex_by_addr(struct graph * graph, assert(graph); - list_for_each(p, &graph->vertices.list) { + llist_for_each(p, &graph->vertices) { struct vertex * e = list_entry(p, struct vertex, next); if (e->addr == addr) return e; @@ -142,7 +139,7 @@ static struct vertex * add_vertex(struct graph * graph, vertex->addr = addr; /* Keep them ordered on address. */ - list_for_each(p, &graph->vertices.list) { + llist_for_each(p, &graph->vertices) { struct vertex * v = list_entry(p, struct vertex, next); if (v->addr > addr) break; @@ -151,7 +148,7 @@ static struct vertex * add_vertex(struct graph * graph, vertex->index = i; - list_add_tail(&vertex->next, p); + llist_add_tail_at(&vertex->next, p, &graph->vertices); /* Increase the index of the vertices to the right. */ list_for_each(p, &vertex->next) { @@ -160,8 +157,6 @@ static struct vertex * add_vertex(struct graph * graph, v->index++; } - ++graph->vertices.len; - return vertex; } @@ -174,10 +169,10 @@ static void del_vertex(struct graph * graph, assert(graph != NULL); assert(vertex != NULL); - list_del(&vertex->next); + llist_del(&vertex->next, &graph->vertices); /* Decrease the index of the vertices to the right. */ - list_for_each(p, &graph->vertices.list) { + llist_for_each(p, &graph->vertices) { struct vertex * v = list_entry(p, struct vertex, next); if (v->addr > vertex->addr) v->index--; @@ -189,8 +184,6 @@ static void del_vertex(struct graph * graph, } free(vertex); - - --graph->vertices.len; } struct graph * graph_create(void) @@ -206,8 +199,7 @@ struct graph * graph_create(void) return NULL; } - graph->vertices.len = 0; - list_head_init(&graph->vertices.list); + llist_init(&graph->vertices); return graph; } @@ -221,7 +213,7 @@ void graph_destroy(struct graph * graph) pthread_mutex_lock(&graph->lock); - list_for_each_safe(p, n, &graph->vertices.list) { + llist_for_each_safe(p, n, &graph->vertices) { struct vertex * e = list_entry(p, struct vertex, next); del_vertex(graph, e); } @@ -230,7 +222,7 @@ void graph_destroy(struct graph * graph) pthread_mutex_destroy(&graph->lock); - assert(graph->vertices.len == 0); + assert(llist_is_empty(&graph->vertices)); free(graph); } @@ -371,7 +363,7 @@ static int get_min_vertex(struct graph * graph, *v = NULL; - list_for_each(p, &graph->vertices.list) { + llist_for_each(p, &graph->vertices) { if (!used[i] && dist[i] < min) { min = dist[i]; index = i; @@ -420,7 +412,7 @@ static int dijkstra(struct graph * graph, memset(*nhops, 0, sizeof(**nhops) * graph->vertices.len); memset(*dist, 0, sizeof(**dist) * graph->vertices.len); - list_for_each(p, &graph->vertices.list) { + llist_for_each(p, &graph->vertices) { v = list_entry(p, struct vertex, next); (*dist)[i++] = (v->addr == src) ? 0 : INT_MAX; } @@ -526,7 +518,7 @@ static int graph_routing_table_simple(struct graph * graph, list_head_init(table); /* Now construct the routing table from the nhops. */ - list_for_each(p, &graph->vertices.list) { + llist_for_each(p, &graph->vertices) { v = list_entry(p, struct vertex, next); /* This is the src */ @@ -624,7 +616,7 @@ static int graph_routing_table_lfa(struct graph * graph, addrs[j] = -1; } - list_for_each(p, &graph->vertices.list) { + llist_for_each(p, &graph->vertices) { v = list_entry(p, struct vertex, next); if (v->addr != s_addr) @@ -650,7 +642,7 @@ static int graph_routing_table_lfa(struct graph * graph, } /* Loop though all nodes to see if we have a LFA for them. */ - list_for_each(p, &graph->vertices.list) { + llist_for_each(p, &graph->vertices) { v = list_entry(p, struct vertex, next); if (v->addr == s_addr) @@ -735,7 +727,7 @@ static int graph_routing_table_ecmp(struct graph * graph, free(nhops); - list_for_each(h, &graph->vertices.list) { + llist_for_each(h, &graph->vertices) { v = list_entry(h, struct vertex, next); if (tmp_dist[v->index] + 1 == (*dist)[v->index]) { n = malloc(sizeof(*n)); @@ -753,7 +745,7 @@ static int graph_routing_table_ecmp(struct graph * graph, list_head_init(table); i = 0; - list_for_each(p, &graph->vertices.list) { + llist_for_each(p, &graph->vertices) { v = list_entry(p, struct vertex, next); if (v->addr == s_addr) { ++i; diff --git a/src/ipcpd/unicast/routing/link-state.c b/src/ipcpd/unicast/routing/link-state.c index 296f00f6..ee558158 100644 --- a/src/ipcpd/unicast/routing/link-state.c +++ b/src/ipcpd/unicast/routing/link-state.c @@ -121,16 +121,8 @@ struct { struct graph * graph; struct { - struct { - struct list_head list; - size_t len; - } nbs; - - struct { - struct list_head list; - size_t len; - } db; - + struct llist nbs; + struct llist db; pthread_rwlock_t lock; }; @@ -189,7 +181,7 @@ static struct adjacency * get_adj(const char * path) assert(path); - list_for_each(p, &ls.db.list) { + llist_for_each(p, &ls.db) { struct adjacency * a = list_entry(p, struct adjacency, next); sprintf(entry, LINK_FMT, LINK_VAL(a->src, a->dst)); if (strcmp(entry, path) == 0) @@ -245,7 +237,7 @@ static int lspb_rib_read(const char * path, pthread_rwlock_rdlock(&ls.lock); - if (ls.db.len + ls.nbs.len == 0) + if (llist_is_empty(&ls.db) && llist_is_empty(&ls.nbs)) goto fail; a = get_adj(entry); @@ -274,7 +266,7 @@ static int lspb_rib_readdir(char *** buf) pthread_rwlock_rdlock(&ls.lock); - if (ls.db.len + ls.nbs.len == 0) { + if (llist_is_empty(&ls.db) && llist_is_empty(&ls.nbs)) { *buf = NULL; goto no_entries; } @@ -284,7 +276,7 @@ static int lspb_rib_readdir(char *** buf) if (*buf == NULL) goto fail_entries; - list_for_each(p, &ls.nbs.list) { + llist_for_each(p, &ls.nbs) { struct nb * nb = list_entry(p, struct nb, next); char * str = (nb->type == NB_DT ? ".dt " : ".mgmt "); sprintf(entry, "%s" ADDR_FMT32 , str, ADDR_VAL32(&nb->addr)); @@ -295,7 +287,7 @@ static int lspb_rib_readdir(char *** buf) strcpy((*buf)[idx++], entry); } - list_for_each(p, &ls.db.list) { + llist_for_each(p, &ls.db) { struct adjacency * a = list_entry(p, struct adjacency, next); sprintf(entry, LINK_FMT, LINK_VAL(a->src, a->dst)); (*buf)[idx] = malloc(strlen(entry) + 1); @@ -333,7 +325,7 @@ static int lspb_add_nb(uint64_t addr, pthread_rwlock_wrlock(&ls.lock); - list_for_each(p, &ls.nbs.list) { + llist_for_each(p, &ls.nbs) { struct nb * el = list_entry(p, struct nb, next); if (addr > el->addr) break; @@ -360,9 +352,7 @@ static int lspb_add_nb(uint64_t addr, nb->fd = fd; nb->type = type; - list_add_tail(&nb->next, p); - - ++ls.nbs.len; + llist_add_tail_at(&nb->next, p, &ls.nbs); log_dbg("Type %s neighbor " ADDR_FMT32 " added.", nb->type == NB_DT ? "dt" : "mgmt", ADDR_VAL32(&addr)); @@ -380,13 +370,12 @@ static int lspb_del_nb(uint64_t addr, pthread_rwlock_wrlock(&ls.lock); - list_for_each_safe(p, h, &ls.nbs.list) { + llist_for_each_safe(p, h, &ls.nbs) { struct nb * nb = list_entry(p, struct nb, next); if (nb->addr != addr || nb->fd != fd) continue; - list_del(&nb->next); - --ls.nbs.len; + llist_del(&nb->next, &ls.nbs); pthread_rwlock_unlock(&ls.lock); log_dbg("Type %s neighbor " ADDR_FMT32 " deleted.", nb->type == NB_DT ? "dt" : "mgmt", ADDR_VAL32(&addr)); @@ -406,7 +395,7 @@ static int nbr_to_fd(uint64_t addr) pthread_rwlock_rdlock(&ls.lock); - list_for_each(p, &ls.nbs.list) { + llist_for_each(p, &ls.nbs) { struct nb * nb = list_entry(p, struct nb, next); if (nb->addr == addr && nb->type == NB_DT) { fd = nb->fd; @@ -494,7 +483,7 @@ static int lspb_add_link(uint64_t src, pthread_rwlock_wrlock(&ls.lock); - list_for_each(p, &ls.db.list) { + llist_for_each(p, &ls.db) { struct adjacency * a = list_entry(p, struct adjacency, next); if (a->dst == dst && a->src == src) { if (a->seqno < seqno) { @@ -521,9 +510,7 @@ static int lspb_add_link(uint64_t src, adj->seqno = seqno; adj->stamp = now.tv_sec; - list_add_tail(&adj->next, p); - - ls.db.len++; + llist_add_tail_at(&adj->next, p, &ls.db); if (graph_update_edge(ls.graph, src, dst, *qs)) log_warn("Failed to add edge to graph."); @@ -543,15 +530,13 @@ static int lspb_del_link(uint64_t src, pthread_rwlock_wrlock(&ls.lock); - list_for_each_safe(p, h, &ls.db.list) { + llist_for_each_safe(p, h, &ls.db) { struct adjacency * a = list_entry(p, struct adjacency, next); if (a->dst == dst && a->src == src) { - list_del(&a->next); + llist_del(&a->next, &ls.db); if (graph_del_edge(ls.graph, src, dst)) log_warn("Failed to delete edge from graph."); - ls.db.len--; - pthread_rwlock_unlock(&ls.lock); set_pff_modified(false); free(a); @@ -599,7 +584,7 @@ static void send_lsm(uint64_t src, lsm.s_addr = hton64(src); lsm.seqno = hton64(seqno); - list_for_each(p, &ls.nbs.list) { + llist_for_each(p, &ls.nbs) { struct nb * nb = list_entry(p, struct nb, next); if (nb->type != NB_MGMT) continue; @@ -628,7 +613,7 @@ static void lspb_replicate(int fd) /* Lock the lspb, copy the lsms and send outside of lock. */ pthread_rwlock_rdlock(&ls.lock); - list_for_each(p, &ls.db.list) { + llist_for_each(p, &ls.db) { struct adjacency * adj; struct adjacency * cpy; adj = list_entry(p, struct adjacency, next); @@ -675,11 +660,11 @@ static void * lsupdate(void * o) pthread_cleanup_push(__cleanup_rwlock_unlock, &ls.lock); - list_for_each_safe(p, h, &ls.db.list) { + llist_for_each_safe(p, h, &ls.db) { struct adjacency * adj; adj = list_entry(p, struct adjacency, next); if (now.tv_sec > adj->stamp + ls.conf.t_timeo) { - list_del(&adj->next); + llist_del(&adj->next, &ls.db); log_dbg(LINK_FMT " timed out.", LINK_VAL(adj->src, adj->dst)); if (graph_del_edge(ls.graph, adj->src, @@ -746,7 +731,7 @@ static void forward_lsm(uint8_t * buf, pthread_cleanup_push(__cleanup_rwlock_unlock, &ls.lock); - list_for_each(p, &ls.nbs.list) { + llist_for_each(p, &ls.nbs) { struct nb * nb = list_entry(p, struct nb, next); if (nb->type != NB_MGMT || nb->fd == in_fd) continue; @@ -1090,16 +1075,13 @@ int link_state_init(struct ls_config * conf, goto fail_fset_create; } - list_head_init(&ls.db.list); - list_head_init(&ls.nbs.list); + llist_init(&ls.db); + llist_init(&ls.nbs); list_head_init(&ls.instances.list); if (rib_reg(Lspb, &r_ops)) goto fail_rib_reg; - ls.db.len = 0; - ls.nbs.len = 0; - return 0; fail_rib_reg: @@ -1131,9 +1113,9 @@ void link_state_fini(void) pthread_rwlock_wrlock(&ls.lock); - list_for_each_safe(p, h, &ls.db.list) { + llist_for_each_safe(p, h, &ls.db) { struct adjacency * a = list_entry(p, struct adjacency, next); - list_del(&a->next); + llist_del(&a->next, &ls.db); free(a); } diff --git a/src/irmd/reg/name.c b/src/irmd/reg/name.c index 4ffedf7a..61a328ec 100644 --- a/src/irmd/reg/name.c +++ b/src/irmd/reg/name.c @@ -69,9 +69,9 @@ struct reg_name * reg_name_create(const struct name_info * info) memset(name, 0, sizeof(*name)); list_head_init(&name->next); - list_head_init(&name->progs.list); - list_head_init(&name->procs.list); - list_head_init(&name->active.list); + llist_init(&name->progs); + llist_init(&name->procs); + llist_init(&name->active); name->info = *info; @@ -87,13 +87,9 @@ void reg_name_destroy(struct reg_name * name) assert(list_is_empty(&name->next)); - assert(name->progs.len == 0); - assert(name->procs.len == 0); - assert(name->active.len == 0); - - assert(list_is_empty(&name->progs.list)); - assert(list_is_empty(&name->procs.list)); - assert(list_is_empty(&name->active.list)); + assert(llist_is_empty(&name->progs)); + assert(llist_is_empty(&name->procs)); + assert(llist_is_empty(&name->active)); free(name); } @@ -106,7 +102,7 @@ static struct proc_entry * __reg_name_get_active(const struct reg_name * name, assert(name != NULL); assert(pid > 0); - list_for_each(p, &name->active.list) { + llist_for_each(p, &name->active) { struct proc_entry * entry; entry = list_entry(p, struct proc_entry, next); if (entry->pid == pid) @@ -122,13 +118,12 @@ static void __reg_name_del_all_active(struct reg_name * name, struct list_head * p; struct list_head * h; - list_for_each_safe(p, h, &name->active.list) { + llist_for_each_safe(p, h, &name->active) { struct proc_entry * entry; entry = list_entry(p, struct proc_entry, next); if (entry->pid == pid) { - list_del(&entry->next); + llist_del(&entry->next, &name->active); free(entry); - --name->active.len; } } } @@ -141,7 +136,7 @@ static struct proc_entry * __reg_name_get_proc(const struct reg_name * name, assert(name != NULL); assert(pid > 0); - list_for_each(p, &name->procs.list) { + llist_for_each(p, &name->procs) { struct proc_entry * entry; entry = list_entry(p, struct proc_entry, next); if (entry->pid == pid) @@ -159,7 +154,7 @@ static struct prog_entry * __reg_name_get_prog(const struct reg_name * name, assert(name != NULL); assert(prog != NULL); - list_for_each(p, &name->progs.list) { + llist_for_each(p, &name->progs) { struct prog_entry * entry; entry = list_entry(p, struct prog_entry, next); if (strcmp(entry->exec[0], prog) == 0) @@ -194,17 +189,15 @@ int reg_name_add_active(struct reg_name * name, switch (name->info.pol_lb) { case LB_RR: /* Round robin policy. */ - list_add_tail(&entry->next, &name->active.list); + llist_add_tail(&entry->next, &name->active); break; case LB_SPILL: /* Keep accepting flows on the current process */ - list_add(&entry->next, &name->active.list); + llist_add(&entry->next, &name->active); break; default: goto fail_unreachable; } - ++name->active.len; - return 0; fail_unreachable: @@ -223,9 +216,7 @@ void reg_name_del_active(struct reg_name * name, if (entry == NULL) return; - list_del(&entry->next); - - --name->active.len; + llist_del(&entry->next, &name->active); free(entry); } @@ -236,10 +227,10 @@ pid_t reg_name_get_active(struct reg_name * name) assert(name != NULL); - if (list_is_empty(&name->active.list)) + if (llist_is_empty(&name->active)) return -1; - e = list_first_entry(&name->active.list, struct proc_entry, next); + e = llist_first_entry(&name->active, struct proc_entry, next); return e->pid; } @@ -262,9 +253,7 @@ int reg_name_add_proc(struct reg_name * name, entry->pid = pid; - list_add(&entry->next, &name->procs.list); - - ++name->procs.len; + llist_add(&entry->next, &name->procs); return 0; @@ -286,12 +275,10 @@ void reg_name_del_proc(struct reg_name * name, __reg_name_del_all_active(name, pid); - list_del(&entry->next); + llist_del(&entry->next, &name->procs); free(entry); - --name->procs.len; - assert(__reg_name_get_proc(name, pid) == NULL); } @@ -324,12 +311,10 @@ int reg_name_add_prog(struct reg_name * name, goto fail_exec; } - list_add(&entry->next, &name->progs.list); + llist_add(&entry->next, &name->progs); log_dbg("Add prog %s to name %s.", exec[0], name->info.name); - ++name->progs.len; - return 0; fail_exec: @@ -350,12 +335,10 @@ void reg_name_del_prog(struct reg_name * name, if (entry == NULL) return; - list_del(&entry->next); + llist_del(&entry->next, &name->progs); __free_prog_entry(entry); - --name->progs.len; - assert(__reg_name_get_prog(name, prog) == NULL); } @@ -372,10 +355,10 @@ char ** reg_name_get_exec(const struct reg_name * name) { struct prog_entry * e; - if (list_is_empty(&name->progs.list)) + if (llist_is_empty(&name->progs)) return NULL; - e = list_first_entry(&name->progs.list, struct prog_entry, next); + e = llist_first_entry(&name->progs, struct prog_entry, next); return e->exec; } diff --git a/src/irmd/reg/name.h b/src/irmd/reg/name.h index 297fb699..59d6d9bd 100644 --- a/src/irmd/reg/name.h +++ b/src/irmd/reg/name.h @@ -38,20 +38,11 @@ struct reg_name { void * crt; } cache; - struct { - struct list_head list; - size_t len; - } progs; /* autostart programs for this name */ + struct llist progs; /* autostart programs for this name */ - struct { - struct list_head list; - size_t len; - } procs; /* processes bound to this name */ + struct llist procs; /* processes bound to this name */ - struct { - struct list_head list; - size_t len; - } active; /* processes actively calling accept */ + struct llist active; /* processes actively calling accept */ }; struct reg_name * reg_name_create(const struct name_info * info); diff --git a/src/irmd/reg/proc.c b/src/irmd/reg/proc.c index 476ed67e..8a7e24c9 100644 --- a/src/irmd/reg/proc.c +++ b/src/irmd/reg/proc.c @@ -55,12 +55,11 @@ static void __reg_proc_clear_names(struct reg_proc * proc) assert(proc != NULL); - list_for_each_safe(p, h, &proc->names) { + llist_for_each_safe(p, h, &proc->names) { struct name_entry * entry; entry = list_entry(p, struct name_entry, next); - list_del(&entry->next); + llist_del(&entry->next, &proc->names); __free_name_entry(entry); - proc->n_names--; } } @@ -85,10 +84,9 @@ struct reg_proc * reg_proc_create(const struct proc_info * info) } list_head_init(&proc->next); - list_head_init(&proc->names); + llist_init(&proc->names); proc->info = *info; - proc->n_names = 0; return proc; @@ -108,9 +106,7 @@ void reg_proc_destroy(struct reg_proc * proc) assert(list_is_empty(&proc->next)); - assert(proc->n_names == 0); - - assert(list_is_empty(&proc->names)); + assert(llist_is_empty(&proc->names)); free(proc); } @@ -120,7 +116,7 @@ static struct name_entry * __reg_proc_get_name(const struct reg_proc * proc, { struct list_head * p; - list_for_each(p, &proc->names) { + llist_for_each(p, &proc->names) { struct name_entry * entry; entry = list_entry(p, struct name_entry, next); if (strcmp(entry->name, name) == 0) @@ -149,9 +145,7 @@ int reg_proc_add_name(struct reg_proc * proc, goto fail_name; } - list_add(&entry->next, &proc->names); - - proc->n_names++; + llist_add(&entry->next, &proc->names); return 0; @@ -170,12 +164,10 @@ void reg_proc_del_name(struct reg_proc * proc, if(entry == NULL) return; - list_del(&entry->next); + llist_del(&entry->next, &proc->names); __free_name_entry(entry); - proc->n_names--; - assert(__reg_proc_get_name(proc, name) == NULL); } diff --git a/src/irmd/reg/proc.h b/src/irmd/reg/proc.h index eeb8f0ab..18cc2803 100644 --- a/src/irmd/reg/proc.h +++ b/src/irmd/reg/proc.h @@ -32,8 +32,7 @@ struct reg_proc { struct proc_info info; - struct list_head names; /* process accepts flows for names */ - size_t n_names; /* number of names */ + struct llist names; /* process accepts flows for names */ struct ssm_flow_set * set; }; diff --git a/src/irmd/reg/prog.c b/src/irmd/reg/prog.c index b53803fa..2d7f9f8d 100644 --- a/src/irmd/reg/prog.c +++ b/src/irmd/reg/prog.c @@ -55,12 +55,11 @@ static void __reg_prog_clear_names(struct reg_prog * prog) assert(prog != NULL); - list_for_each_safe(p, h, &prog->names) { + llist_for_each_safe(p, h, &prog->names) { struct name_entry * entry; entry = list_entry(p, struct name_entry, next); - list_del(&entry->next); + llist_del(&entry->next, &prog->names); __free_name_entry(entry); - prog->n_names--; } } @@ -77,10 +76,9 @@ struct reg_prog * reg_prog_create(const struct prog_info * info) } list_head_init(&p->next); - list_head_init(&p->names); + llist_init(&p->names); p->info = *info; - p->n_names = 0; return p; @@ -96,9 +94,7 @@ void reg_prog_destroy(struct reg_prog * prog) assert(list_is_empty(&prog->next)); - assert(prog->n_names == 0); - - assert(list_is_empty(&prog->names)); + assert(llist_is_empty(&prog->names)); free(prog); } @@ -108,7 +104,7 @@ static struct name_entry * __reg_prog_get_name(const struct reg_prog * prog, { struct list_head * p; - list_for_each(p, &prog->names) { + llist_for_each(p, &prog->names) { struct name_entry * entry; entry = list_entry(p, struct name_entry, next); if (strcmp(entry->name, name) == 0) @@ -137,9 +133,7 @@ int reg_prog_add_name(struct reg_prog * prog, goto fail_name; } - list_add(&entry->next, &prog->names); - - prog->n_names++; + llist_add(&entry->next, &prog->names); return 0; @@ -158,12 +152,10 @@ void reg_prog_del_name(struct reg_prog * prog, if (entry == NULL) return; - list_del(&entry->next); + llist_del(&entry->next, &prog->names); __free_name_entry(entry); - prog->n_names--; - assert(__reg_prog_get_name(prog, name) == NULL); } diff --git a/src/irmd/reg/prog.h b/src/irmd/reg/prog.h index 045711c8..e52b8e15 100644 --- a/src/irmd/reg/prog.h +++ b/src/irmd/reg/prog.h @@ -33,8 +33,7 @@ struct reg_prog { struct prog_info info; - struct list_head names; /* names to listen for */ - size_t n_names; /* number of names in list */ + struct llist names; /* names to listen for */ }; struct reg_prog * reg_prog_create(const struct prog_info * info); diff --git a/src/irmd/reg/reg.c b/src/irmd/reg/reg.c index da2b415e..64aa1513 100644 --- a/src/irmd/reg/reg.c +++ b/src/irmd/reg/reg.c @@ -47,31 +47,18 @@ The IPC Resource Manager - Registry #define ID_OFFT 1 /* reserve some flow_ids */ struct { - struct bmp * flow_ids; /* flow_ids for flows */ - - struct list_head flows; /* flow information */ - size_t n_flows; /* number of flows */ - - struct list_head ipcps; /* list of ipcps in system */ - size_t n_ipcps; /* number of ipcps */ - - struct list_head names; /* registered names known */ - size_t n_names; /* number of names */ - - struct list_head pools; /* per-user pools */ - size_t n_pools; /* number of pools */ - - struct list_head procs; /* processes */ - size_t n_procs; /* number of processes */ - - struct list_head progs; /* programs known */ - size_t n_progs; /* number of programs */ - - struct list_head spawned; /* child processes */ - size_t n_spawned; /* number of child processes */ - - pthread_mutex_t mtx; /* registry lock */ - pthread_cond_t cond; /* condvar for reg changes */ + struct bmp * ids; /* flow bitmap */ + + struct llist flows; /* list of flows */ + struct llist ipcps; /* list of ipcps in system */ + struct llist names; /* registered names known */ + struct llist pools; /* per-user pools */ + struct llist procs; /* processes known */ + struct llist progs; /* programs known */ + struct llist spawned; /* child processes */ + + pthread_mutex_t mtx; /* registry lock */ + pthread_cond_t cond; /* condvar for reg changes */ } reg; struct pid_entry { @@ -85,7 +72,7 @@ static struct reg_flow * __reg_get_flow(int flow_id) assert(flow_id >= ID_OFFT); - list_for_each(p, ®.flows) { + llist_for_each(p, ®.flows) { struct reg_flow * entry; entry = list_entry(p, struct reg_flow, next); if (entry->info.id == flow_id) @@ -99,7 +86,7 @@ static struct reg_flow * __reg_get_accept_flow(pid_t pid) { struct list_head * p; - list_for_each(p, ®.flows) { + llist_for_each(p, ®.flows) { struct reg_flow * entry; entry = list_entry(p, struct reg_flow, next); if (entry->info.state != FLOW_ACCEPT_PENDING) @@ -117,7 +104,7 @@ static struct list_head * __reg_after_flow(int flow_id) assert(flow_id >= ID_OFFT); - list_for_each(p, ®.flows) { + llist_for_each(p, ®.flows) { struct reg_flow * entry; entry = list_entry(p, struct reg_flow, next); if (entry->info.id > flow_id) @@ -133,7 +120,7 @@ static struct reg_ipcp * __reg_get_ipcp(pid_t pid) assert(pid > 0); - list_for_each(p, ®.ipcps) { + llist_for_each(p, ®.ipcps) { struct reg_ipcp * entry; entry = list_entry(p, struct reg_ipcp, next); if (entry->info.pid == pid) @@ -147,7 +134,7 @@ static struct reg_ipcp * __reg_get_ipcp_by_layer(const char * layer) { struct list_head * p; - list_for_each(p, ®.ipcps) { + llist_for_each(p, ®.ipcps) { struct reg_ipcp * entry; entry = list_entry(p, struct reg_ipcp, next); if (strcmp(entry->layer.name, layer) == 0) @@ -164,7 +151,7 @@ static struct list_head * __reg_after_ipcp(const struct ipcp_info * info) assert(info != NULL); - list_for_each(p, ®.ipcps) { + llist_for_each(p, ®.ipcps) { struct reg_ipcp * entry; entry = list_entry(p, struct reg_ipcp, next); if (entry->info.type < info->type) @@ -186,7 +173,7 @@ static struct reg_name * __reg_get_name(const char * name) assert(name != NULL); - list_for_each(p, ®.names) { + llist_for_each(p, ®.names) { struct reg_name * entry; entry = list_entry(p, struct reg_name, next); if (strcmp(entry->info.name, name) == 0) @@ -229,7 +216,7 @@ static struct list_head * __reg_after_name(const char * name) assert(name != NULL); - list_for_each(p, ®.names) { + llist_for_each(p, ®.names) { struct reg_name * entry; entry = list_entry(p, struct reg_name, next); if (strcmp(entry->info.name, name) > 0) @@ -243,7 +230,7 @@ static struct reg_pool * __reg_get_pool(uid_t uid) { struct list_head * p; - list_for_each(p, ®.pools) { + llist_for_each(p, ®.pools) { struct reg_pool * entry; entry = list_entry(p, struct reg_pool, next); if (entry->uid == uid) @@ -257,7 +244,7 @@ static struct reg_proc * __reg_get_proc(pid_t pid) { struct list_head * p; - list_for_each(p, ®.procs) { + llist_for_each(p, ®.procs) { struct reg_proc * entry; entry = list_entry(p, struct reg_proc, next); if (entry->info.pid == pid) @@ -271,7 +258,7 @@ static struct list_head * __reg_after_proc(pid_t pid) { struct list_head * p; - list_for_each(p, ®.procs) { + llist_for_each(p, ®.procs) { struct reg_proc * entry; entry = list_entry(p, struct reg_proc, next); if (entry->info.pid > pid) @@ -285,7 +272,7 @@ static void __reg_kill_all_proc(int signal) { struct list_head * p; - list_for_each(p, ®.procs) { + llist_for_each(p, ®.procs) { struct reg_proc * entry; entry = list_entry(p, struct reg_proc, next); kill(entry->info.pid, signal); @@ -296,7 +283,7 @@ static pid_t __reg_get_dead_proc(void) { struct list_head * p; - list_for_each(p, ®.procs) { + llist_for_each(p, ®.procs) { struct reg_proc * entry; entry = list_entry(p, struct reg_proc, next); if (kill(entry->info.pid, 0) < 0) @@ -311,7 +298,7 @@ static void __reg_cancel_flows_for_proc(pid_t pid) struct list_head * p; bool changed = false; - list_for_each(p, ®.flows) { + llist_for_each(p, ®.flows) { struct reg_flow * entry; entry = list_entry(p, struct reg_flow, next); if (entry->info.n_pid != pid) @@ -337,7 +324,7 @@ static struct pid_entry * __reg_get_spawned(pid_t pid) { struct list_head * p; - list_for_each(p, ®.spawned) { + llist_for_each(p, ®.spawned) { struct pid_entry * entry; entry = list_entry(p, struct pid_entry, next); if (entry->pid == pid) @@ -351,7 +338,7 @@ static struct list_head * __reg_after_spawned(pid_t pid) { struct list_head * p; - list_for_each(p, ®.spawned) { + llist_for_each(p, ®.spawned) { struct pid_entry * entry; entry = list_entry(p, struct pid_entry, next); if (entry->pid > pid) @@ -365,7 +352,7 @@ static void __reg_kill_all_spawned(int signal) { struct list_head * p; - list_for_each(p, ®.spawned) { + llist_for_each(p, ®.spawned) { struct pid_entry * entry; entry = list_entry(p, struct pid_entry, next); kill(entry->pid, signal); @@ -374,17 +361,17 @@ static void __reg_kill_all_spawned(int signal) static pid_t __reg_first_spawned(void) { - if (list_is_empty(®.spawned)) + if (llist_is_empty(®.spawned)) return -1; - return list_first_entry(®.spawned, struct pid_entry, next)->pid; + return llist_first_entry(®.spawned, struct pid_entry, next)->pid; } static struct reg_prog * __reg_get_prog(const char * name) { struct list_head * p; - list_for_each(p, ®.progs) { + llist_for_each(p, ®.progs) { struct reg_prog * entry; entry = list_entry(p, struct reg_prog, next); if (strcmp(entry->info.name, name) == 0) @@ -398,7 +385,7 @@ static char ** __reg_get_exec(const char * name) { struct list_head * p; - list_for_each(p, ®.names) { + llist_for_each(p, ®.names) { struct reg_name * entry; entry = list_entry(p, struct reg_name, next); if (strcmp(entry->info.name, name) == 0) @@ -412,7 +399,7 @@ static struct list_head * __reg_after_prog(const char * name) { struct list_head * p; - list_for_each(p, ®.progs) { + llist_for_each(p, ®.progs) { struct reg_prog * entry; entry = list_entry(p, struct reg_prog, next); if (strcmp(entry->info.name, name) > 0) @@ -426,7 +413,7 @@ static void __reg_del_name_from_procs(const char * name) { struct list_head * p; - list_for_each(p, ®.procs) { + llist_for_each(p, ®.procs) { struct reg_proc * proc; proc = list_entry(p, struct reg_proc, next); reg_proc_del_name(proc, name); @@ -437,7 +424,7 @@ static void __reg_del_name_from_progs(const char * name) { struct list_head * p; - list_for_each(p, ®.progs) { + llist_for_each(p, ®.progs) { struct reg_prog * prog; prog = list_entry(p, struct reg_prog, next); reg_prog_del_name(prog, name); @@ -449,13 +436,13 @@ static void __reg_proc_update_names(struct reg_proc * proc) struct list_head * p; struct reg_prog * prog; - assert(list_is_empty(&proc->names)); + assert(llist_is_empty(&proc->names)); prog = __reg_get_prog(proc->info.prog); if (prog == NULL) return; - list_for_each(p, ®.names) { + llist_for_each(p, ®.names) { struct reg_name * name; name = list_entry(p, struct reg_name, next); assert(!reg_name_has_proc(name, proc->info.pid)); @@ -470,7 +457,7 @@ static void __reg_del_proc_from_names(pid_t pid) { struct list_head * p; - list_for_each(p, ®.names) { + llist_for_each(p, ®.names) { struct reg_name * name; name = list_entry(p, struct reg_name, next); reg_name_del_proc(name, pid); @@ -481,7 +468,7 @@ static void __reg_del_prog_from_names(const char * prog) { struct list_head * p; - list_for_each(p, ®.names) { + llist_for_each(p, ®.names) { struct reg_name * name; name = list_entry(p, struct reg_name, next); reg_name_del_prog(name, prog); @@ -496,7 +483,7 @@ static int __reg_add_active_proc(pid_t pid) assert(pid > 0); - list_for_each(p, ®.names) { + llist_for_each(p, ®.names) { struct reg_name * name; name = list_entry(p, struct reg_name, next); if (reg_name_has_proc(name, pid)) { @@ -518,7 +505,7 @@ static void __reg_del_active_proc(pid_t pid) assert(pid > 0); - list_for_each(p, ®.names) { + llist_for_each(p, ®.names) { struct reg_name * name; name = list_entry(p, struct reg_name, next); reg_name_del_active(name, pid); @@ -547,21 +534,21 @@ int reg_init(void) goto fail_cond; } - reg.flow_ids = bmp_create(SYS_MAX_FLOWS -ID_OFFT, ID_OFFT); - if (reg.flow_ids == NULL) { + reg.ids = bmp_create(SYS_MAX_FLOWS - ID_OFFT, ID_OFFT); + if (reg.ids == NULL) { log_err("Failed to create flow_ids bitmap."); goto fail_flow_ids; } pthread_condattr_destroy(&cattr); - list_head_init(®.flows); - list_head_init(®.ipcps); - list_head_init(®.names); - list_head_init(®.pools); - list_head_init(®.procs); - list_head_init(®.progs); - list_head_init(®.spawned); + llist_init(®.flows); + llist_init(®.ipcps); + llist_init(®.names); + llist_init(®.pools); + llist_init(®.procs); + llist_init(®.progs); + llist_init(®.spawned); return 0; @@ -582,63 +569,56 @@ void reg_clear(void) pthread_mutex_lock(®.mtx); - list_for_each_safe(p, h, ®.spawned) { + llist_for_each_safe(p, h, ®.spawned) { struct pid_entry * entry; entry = list_entry(p, struct pid_entry, next); - list_del(&entry->next); + llist_del(&entry->next, ®.spawned); free(entry); - reg.n_spawned--; } - list_for_each_safe(p, h, ®.progs) { + llist_for_each_safe(p, h, ®.progs) { struct reg_prog * entry; entry = list_entry(p, struct reg_prog, next); - list_del(&entry->next); + llist_del(&entry->next, ®.progs); __reg_del_prog_from_names(entry->info.path); reg_prog_destroy(entry); - reg.n_progs--; } - list_for_each_safe(p, h, ®.procs) { + llist_for_each_safe(p, h, ®.procs) { struct reg_proc * entry; entry = list_entry(p, struct reg_proc, next); - list_del(&entry->next); + llist_del(&entry->next, ®.procs); __reg_del_proc_from_names(entry->info.pid); reg_proc_destroy(entry); - reg.n_procs--; } - list_for_each_safe(p, h, ®.pools) { + llist_for_each_safe(p, h, ®.pools) { struct reg_pool * entry; entry = list_entry(p, struct reg_pool, next); - list_del(&entry->next); + llist_del(&entry->next, ®.pools); entry->refcount = 0; /* Force destroy during cleanup */ reg_pool_destroy(entry); - reg.n_pools--; } - list_for_each_safe(p, h, ®.flows) { + llist_for_each_safe(p, h, ®.flows) { struct reg_flow * entry; entry = list_entry(p, struct reg_flow, next); - list_del(&entry->next); + llist_del(&entry->next, ®.flows); reg_flow_destroy(entry); - reg.n_flows--; } - list_for_each_safe(p, h, ®.names) { + llist_for_each_safe(p, h, ®.names) { struct reg_name * entry; entry = list_entry(p, struct reg_name, next); - list_del(&entry->next); + llist_del(&entry->next, ®.names); reg_name_destroy(entry); - reg.n_names--; } - list_for_each_safe(p, h, ®.ipcps) { + llist_for_each_safe(p, h, ®.ipcps) { struct reg_ipcp * entry; entry = list_entry(p, struct reg_ipcp, next); - list_del(&entry->next); + llist_del(&entry->next, ®.ipcps); reg_ipcp_destroy(entry); - reg.n_ipcps--; } pthread_mutex_unlock(®.mtx); @@ -646,23 +626,15 @@ void reg_clear(void) void reg_fini(void) { - assert(list_is_empty(®.spawned)); - assert(list_is_empty(®.progs)); - assert(list_is_empty(®.procs)); - assert(list_is_empty(®.pools)); - assert(list_is_empty(®.names)); - assert(list_is_empty(®.ipcps)); - assert(list_is_empty(®.flows)); - - assert(reg.n_spawned == 0); - assert(reg.n_progs == 0); - assert(reg.n_procs == 0); - assert(reg.n_pools == 0); - assert(reg.n_names == 0); - assert(reg.n_ipcps == 0); - assert(reg.n_flows == 0); + assert(llist_is_empty(®.spawned)); + assert(llist_is_empty(®.progs)); + assert(llist_is_empty(®.procs)); + assert(llist_is_empty(®.pools)); + assert(llist_is_empty(®.names)); + assert(llist_is_empty(®.ipcps)); + assert(llist_is_empty(®.flows)); - bmp_destroy(reg.flow_ids); + bmp_destroy(reg.ids); if (pthread_cond_destroy(®.cond) != 0) log_warn("Failed to destroy condvar."); @@ -682,8 +654,8 @@ int reg_create_flow(struct flow_info * info) pthread_mutex_lock(®.mtx); - info->id = bmp_allocate(reg.flow_ids); - if (!bmp_is_id_valid(reg.flow_ids, info->id)) { + info->id = bmp_allocate(reg.ids); + if (!bmp_is_id_valid(reg.ids, info->id)) { log_err("Failed to allocate flow id."); goto fail_id; } @@ -694,16 +666,14 @@ int reg_create_flow(struct flow_info * info) goto fail_flow; } - list_add(&f->next, __reg_after_flow(info->id)); - - reg.n_flows++; + llist_add_at(&f->next, __reg_after_flow(info->id), ®.flows); pthread_mutex_unlock(®.mtx); return 0; fail_flow: - bmp_release(reg.flow_ids, info->id); + bmp_release(reg.ids, info->id); info->id = 0; fail_id: pthread_mutex_unlock(®.mtx); @@ -722,11 +692,9 @@ int reg_destroy_flow(int flow_id) goto no_flow; } - list_del(&f->next); - - reg.n_flows--; + llist_del(&f->next, ®.flows); - bmp_release(reg.flow_ids, flow_id); + bmp_release(reg.ids, flow_id); pthread_mutex_unlock(®.mtx); @@ -785,11 +753,10 @@ int reg_create_ipcp(const struct ipcp_info * info) entry->pid = info->pid; - list_add_tail(&ipcp->next, __reg_after_ipcp(info)); - list_add(&entry->next, __reg_after_spawned(info->pid)); - - reg.n_ipcps++; - reg.n_spawned++; + llist_add_tail_at(&ipcp->next, __reg_after_ipcp(info), ®.ipcps); + llist_add_at(&entry->next, + __reg_after_spawned(info->pid), + ®.spawned); pthread_mutex_unlock(®.mtx); @@ -879,16 +846,16 @@ int reg_list_ipcps(ipcp_list_msg_t *** ipcps) pthread_mutex_lock(®.mtx); - if (reg.n_ipcps == 0) + if (llist_is_empty(®.ipcps)) goto finish; - *ipcps = malloc(reg.n_ipcps * sizeof(**ipcps)); + *ipcps = malloc(reg.ipcps.len * sizeof(**ipcps)); if (*ipcps == NULL) { log_err("Failed to malloc ipcps."); goto fail_malloc; } - list_for_each(p, ®.ipcps) { + llist_for_each(p, ®.ipcps) { struct reg_ipcp * entry; entry = list_entry(p, struct reg_ipcp, next); if (__get_ipcp_info(&(*ipcps)[i], entry) < 0) @@ -930,9 +897,7 @@ int reg_create_name(const struct name_info * info) goto fail_name; } - list_add(&n->next, __reg_after_name(info->name)); - - reg.n_names++; + llist_add_at(&n->next, __reg_after_name(info->name), ®.names); pthread_mutex_unlock(®.mtx); return 0; @@ -961,9 +926,7 @@ int reg_destroy_name(const char * name) __reg_del_name_from_procs(name); __reg_del_name_from_progs(name); - list_del(&n->next); - - reg.n_names--; + llist_del(&n->next, ®.names); pthread_mutex_unlock(®.mtx); @@ -1034,7 +997,7 @@ int reg_get_name_for_hash(char * buf, pthread_mutex_lock(®.mtx); - list_for_each(p, ®.names) { + llist_for_each(p, ®.names) { struct reg_name * n = list_entry(p, struct reg_name, next); str_hash(algo, thash, n->info.name); if (memcmp(thash, hash, len) == 0) { @@ -1076,16 +1039,16 @@ int reg_list_names(name_info_msg_t *** names) pthread_mutex_lock(®.mtx); - if (reg.n_names == 0) + if (llist_is_empty(®.names)) goto finish; - *names = malloc(reg.n_names * sizeof(**names)); + *names = malloc(reg.names.len * sizeof(**names)); if (*names == NULL) { log_err("Failed to malloc names."); goto fail_malloc; } - list_for_each(p, ®.names) { + llist_for_each(p, ®.names) { struct reg_name * entry; entry = list_entry(p, struct reg_name, next); (*names)[i] = name_info_s_to_msg(&entry->info); @@ -1138,8 +1101,7 @@ int reg_prepare_pool(uid_t uid, pthread_mutex_unlock(®.mtx); return -1; } - list_add(&pool->next, ®.pools); - reg.n_pools++; + llist_add(&pool->next, ®.pools); } reg_pool_ref(pool); @@ -1170,9 +1132,7 @@ int reg_create_proc(const struct proc_info * info) __reg_proc_update_names(proc); - list_add(&proc->next, __reg_after_proc(info->pid)); - - reg.n_procs++; + llist_add_at(&proc->next, __reg_after_proc(info->pid), ®.procs); pthread_cond_broadcast(®.cond); @@ -1198,29 +1158,25 @@ int reg_destroy_proc(pid_t pid) if (proc != NULL) { if (!is_ouroboros_member_uid(proc->info.uid)) pool = __reg_get_pool(proc->info.uid); - list_del(&proc->next); - reg.n_procs--; + llist_del(&proc->next, ®.procs); reg_proc_destroy(proc); __reg_del_proc_from_names(pid); __reg_cancel_flows_for_proc(pid); if (pool != NULL && reg_pool_unref(pool) == 0) { - list_del(&pool->next); - reg.n_pools--; + llist_del(&pool->next, ®.pools); reg_pool_destroy(pool); } } spawn = __reg_get_spawned(pid); if (spawn != NULL) { - list_del(&spawn->next); - reg.n_spawned--; + llist_del(&spawn->next, ®.spawned); free(spawn); } ipcp = __reg_get_ipcp(pid); if (ipcp != NULL) { - list_del(&ipcp->next); - reg.n_ipcps--; + llist_del(&ipcp->next, ®.ipcps); reg_ipcp_destroy(ipcp); } @@ -1315,9 +1271,7 @@ int reg_create_spawned(pid_t pid) entry->pid = pid; - list_add(&entry->next, __reg_after_spawned(pid)); - - reg.n_spawned++; + llist_add_at(&entry->next, __reg_after_spawned(pid), ®.spawned); pthread_mutex_unlock(®.mtx); @@ -1487,9 +1441,7 @@ int reg_create_prog(const struct prog_info * info) goto fail_prog; } - list_add(&prog->next, __reg_after_prog(info->name)); - - reg.n_progs++; + llist_add_at(&prog->next, __reg_after_prog(info->name), ®.progs); exists: pthread_mutex_unlock(®.mtx); @@ -1517,9 +1469,7 @@ int reg_destroy_prog(const char * name) __reg_del_prog_from_names(prog->info.path); - list_del(&prog->next); - - reg.n_progs--; + llist_del(&prog->next, ®.progs); pthread_mutex_unlock(®.mtx); diff --git a/src/irmd/reg/tests/name_test.c b/src/irmd/reg/tests/name_test.c index 4812fb9d..403c8a6c 100644 --- a/src/irmd/reg/tests/name_test.c +++ b/src/irmd/reg/tests/name_test.c @@ -88,7 +88,7 @@ static int test_reg_name_add_proc(void) reg_name_del_proc(n, TEST_PID); - if (n->procs.len != 0) { + if (!llist_is_empty(&n->procs)) { printf("Proc not removed from list.\n"); goto fail; } @@ -138,7 +138,7 @@ static int test_reg_name_add_prog(void) reg_name_del_prog(n, TEST_PROG); - if (n->progs.len != 0) { + if (!llist_is_empty(&n->progs)) { printf("Prog not removed from list.\n"); goto fail; } @@ -263,12 +263,12 @@ static int test_reg_name_add_active(enum pol_balance lb) reg_name_del_proc(n, TEST_PID); - if (n->procs.len != 0) { + if (!llist_is_empty(&n->procs)) { printf("Procs list not cleared.\n"); goto fail; } - if (n->active.len != 0) { + if (!llist_is_empty(&n->active)) { printf("Active list not cleared.\n"); goto fail; } diff --git a/src/irmd/reg/tests/proc_test.c b/src/irmd/reg/tests/proc_test.c index 2e2649d7..a85f4039 100644 --- a/src/irmd/reg/tests/proc_test.c +++ b/src/irmd/reg/tests/proc_test.c @@ -77,7 +77,7 @@ static int test_reg_proc_add_name(void) goto fail; } - if (proc->n_names != 1) { + if (proc->names.len != 1) { printf("n_names not updated.\n"); goto fail; } @@ -89,7 +89,7 @@ static int test_reg_proc_add_name(void) reg_proc_del_name(proc, name); - if (proc->n_names != 0) { + if (!llist_is_empty(&proc->names)) { printf("n_names not updated.\n"); goto fail; } diff --git a/src/irmd/reg/tests/prog_test.c b/src/irmd/reg/tests/prog_test.c index 9c40de92..91264aba 100644 --- a/src/irmd/reg/tests/prog_test.c +++ b/src/irmd/reg/tests/prog_test.c @@ -73,7 +73,7 @@ static int test_reg_prog_add_name(void) goto fail; } - if (prog->n_names != 1) { + if (prog->names.len != 1) { printf("n_names not updated.\n"); goto fail; } @@ -85,7 +85,7 @@ static int test_reg_prog_add_name(void) reg_prog_del_name(prog, name); - if (prog->n_names != 0) { + if (!llist_is_empty(&prog->names)) { printf("n_names not updated.\n"); goto fail; } diff --git a/src/irmd/reg/tests/reg_test.c b/src/irmd/reg/tests/reg_test.c index 4eb75b03..4d7e30ef 100644 --- a/src/irmd/reg/tests/reg_test.c +++ b/src/irmd/reg/tests/reg_test.c @@ -89,7 +89,7 @@ static int test_reg_create_flow(void) goto fail; } - if (reg.n_flows != 1) { + if (reg.flows.len != 1) { printf("n_flows was not updated.\n"); goto fail; } @@ -104,8 +104,8 @@ static int test_reg_create_flow(void) goto fail; } - if (reg.n_flows != 0) { - printf("n_flows was not updated.\n"); + if (!llist_is_empty(®.flows)) { + printf("flows.len was not updated.\n"); goto fail; } @@ -163,7 +163,7 @@ static int test_reg_allocate_flow_timeout(void) reg_destroy_flow(info.id); - if (reg.n_flows != 0) { + if (!llist_is_empty(®.flows)) { printf("Flow did not destroy.\n"); goto fail; } @@ -517,7 +517,7 @@ static int test_reg_create_ipcp(void) goto fail; } - if (reg.n_ipcps != 1) { + if (reg.ipcps.len != 1) { printf("n_ipcps was not updated.\n"); goto fail; } @@ -532,8 +532,8 @@ static int test_reg_create_ipcp(void) goto fail; } - if (reg.n_ipcps != 0) { - printf("n_ipcps was not updated.\n"); + if (reg.ipcps.len != 0) { + printf("ipcps.len was not updated.\n"); goto fail; } @@ -761,7 +761,7 @@ static int test_reg_create_name(void) goto fail; } - if (reg.n_names != 1) { + if (reg.names.len != 1) { printf("n_names was not updated.\n"); goto fail; } @@ -776,7 +776,7 @@ static int test_reg_create_name(void) goto fail; } - if (reg.n_names != 0) { + if (!llist_is_empty(®.names)) { printf("n_names was not updated.\n"); goto fail; } @@ -874,7 +874,7 @@ static int test_reg_create_proc(void) goto fail; } - if (reg.n_procs != 1) { + if (reg.procs.len != 1) { printf("n_procs was not updated.\n"); goto fail; } @@ -889,7 +889,7 @@ static int test_reg_create_proc(void) goto fail; } - if (reg.n_procs != 0) { + if (!llist_is_empty(®.procs)) { printf("n_procs was not updated.\n"); goto fail; } @@ -927,7 +927,7 @@ static int test_reg_spawned(void) goto fail; } - if (reg.n_spawned != 1) { + if (reg.spawned.len != 1) { printf("n_spawned was not updated.\n"); goto fail; } @@ -942,7 +942,7 @@ static int test_reg_spawned(void) goto fail; } - if (reg.n_spawned != 0) { + if (!llist_is_empty(®.spawned)) { printf("n_spawned was not updated.\n"); goto fail; } @@ -975,7 +975,7 @@ static int test_reg_create_prog(void) goto fail; } - if (reg.n_progs != 1) { + if (reg.progs.len != 1) { printf("n_progs was not updated.\n"); goto fail; } @@ -990,7 +990,7 @@ static int test_reg_create_prog(void) goto fail; } - if (reg.n_progs != 0) { + if (!llist_is_empty(®.progs)) { printf("n_progs was not updated.\n"); goto fail; } @@ -1521,8 +1521,8 @@ static int test_wait_ipcp_boot_fail(void) goto fail; } - if (reg.n_ipcps != 0) { - printf("n_ipcps was not updated.\n"); + if (!llist_is_empty(®.ipcps)) { + printf("ipcps.len was not updated.\n"); goto fail; } diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index c4306b00..79263924 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -20,7 +20,6 @@ set(SOURCE_FILES_COMMON crc32.c crypt.c hash.c - list.c lockfile.c logs.c md5.c diff --git a/src/lib/list.c b/src/lib/list.c deleted file mode 100644 index 9cc1e443..00000000 --- a/src/lib/list.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Ouroboros - Copyright (C) 2016 - 2026 - * - * Simple doubly linked list implementation. - * - * Dimitri Staessens - * Sander Vrijders - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., http://www.fsf.org/about/contact/. - */ - -#include - -#include - -void list_head_init(struct list_head * h) -{ - h->nxt = h; - h->prv = h; -} - -static void add_list(struct list_head * n, - struct list_head * prv, - struct list_head * nxt) -{ - nxt->prv = n; - n->nxt = nxt; - n->prv = prv; - prv->nxt = n; -} - -static void del_list(struct list_head * prv, - struct list_head * nxt) -{ - nxt->prv = prv; - prv->nxt = nxt; -} - -void list_add(struct list_head * n, - struct list_head * h) -{ - add_list(n, h, h->nxt); -} - -void list_add_tail(struct list_head * n, - struct list_head * h) -{ - add_list(n, h->prv, h); -} - -void list_del(struct list_head * e) -{ - del_list(e->prv, e->nxt); - e->nxt = e->prv = e; -} - -bool list_is_empty(const struct list_head * h) -{ - return h->nxt == h; -} - -void list_move(struct list_head * n, - struct list_head * h) -{ - del_list(n->prv, n->nxt); - add_list(n, h, h->nxt); -} -- cgit v1.2.3