diff --git a/src/core/allsta.c b/src/core/allsta.c index f108e1452d93f95da5442f8f5ad60cbf65aa6d2d..f577f4aa9f14f910132929f5ab5145f966d5402d 100644 --- a/src/core/allsta.c +++ b/src/core/allsta.c @@ -15,6 +15,7 @@ #include <easy/easy.h> #include "utils.h" #include "debug.h" +#include "hlist.h" #include "allsta.h" /* hash table of all active stas in the network */ diff --git a/src/core/cntlr.c b/src/core/cntlr.c index 11ea70575b6ff1cfb7e1a985a0a02f70566449cb..423edf98f71c4cb2434e6b6a2ce358c5a2c80deb 100644 --- a/src/core/cntlr.c +++ b/src/core/cntlr.c @@ -41,6 +41,7 @@ #include "config.h" #include "cntlr.h" #include "comm.h" +#include "hlist.h" #include "allsta.h" #include "cntlr_ubus.h" #include "cntlr_map.h" diff --git a/src/core/cntlr_ubus.c b/src/core/cntlr_ubus.c index 2b5d3c23fa47bd64549288cca6898fb116ee146e..1420c25554756b971834e920c4d06c25a8f770ce 100644 --- a/src/core/cntlr_ubus.c +++ b/src/core/cntlr_ubus.c @@ -31,6 +31,7 @@ #include "debug.h" #include "config.h" #include "cntlr.h" +#include "hlist.h" #include "allsta.h" #include "cntlr_map.h" #include "cntlr_ubus.h" diff --git a/src/utils/hlist.h b/src/utils/hlist.h new file mode 100644 index 0000000000000000000000000000000000000000..faf0078901eff2767896608ed87df8e4fceb131e --- /dev/null +++ b/src/utils/hlist.h @@ -0,0 +1,101 @@ +/* + * hlist.h - stripped down version of hash list implementation using + * singly linked list. + * Doubly linked list is wastage of space for big hash-tables. If cost of + * iterating a hash list is significant, it means the hash function is NOT + * formulated well and should be revisited. + * + * Copyright (C) 2019 IOPSYS Software Solutions AB. All rights reserved. + * + * Author: anjan.chanda@iopsys.eu + * + */ + +#ifndef _HLIST_H +#define _HLIST_H + +struct hlist_node { + struct hlist_node *next; +}; + +struct hlist_head { + struct hlist_node *first; +}; + +#define HLIST_HEAD_INIT(name) { &(name) } + +#define HLIST_HEAD(name) struct hlist_head name = HLIST_HEAD_INIT(name) + +static inline void INIT_HLIST_HEAD(struct hlist_head *h) +{ + h->first = NULL; +} + +static inline void INIT_HLIST_NODE(struct hlist_node *n) +{ + n->next = NULL; +} + +static inline int hlist_empty(const struct hlist_head *h) +{ + return !h->first; +} + +static inline void __hlist_del(struct hlist_node *prev, struct hlist_node *n) +{ + prev->next = n->next; + n->next = NULL; +} + +static inline void hlist_del(struct hlist_node *n, struct hlist_head *h) +{ + struct hlist_node *p; + + if (h->first == n) { + h->first = NULL; + n->next = NULL; + return; + } + + for (p = h->first; p; p = p->next) { + if (p->next == n) + __hlist_del(p, n); + } +} + +static inline void _hlist_add(struct hlist_node *_new, struct hlist_head *h) +{ + _new->next = h->first; + h->first = _new; +} + +static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) +{ + _hlist_add(n, h); +} + +#define hlist_for_each(pos, head) \ + for (pos = (head)->first; pos ; pos = pos->next) + +#define hlist_for_each_safe(pos, n, head) \ + for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \ + pos = n) + +#define hlist_entry(ptr, type, member) container_of(ptr, type, member) + +#define hlist_entry_safe(ptr, type, member) \ + ({ typeof(ptr) ____ptr = (ptr); \ + ____ptr ? hlist_entry(____ptr, type, member) : NULL; \ + }) + +#define hlist_for_each_entry(pos, head, member) \ + for (pos = hlist_entry_safe((head)->first, typeof(*(pos)), member); \ + pos; \ + pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member)) + +#define hlist_for_each_entry_safe(pos, n, head, member) \ + for (pos = hlist_entry_safe((head)->first, typeof(*pos), member); \ + pos && ({ n = pos->member.next; 1; }); \ + pos = hlist_entry_safe(n, typeof(*pos), member)) + +#endif /* _HLIST_H */