Kevin O'Connor | e097a75 | 2013-06-08 21:49:12 -0400 | [diff] [blame] | 1 | #ifndef __LIST_H |
| 2 | #define __LIST_H |
| 3 | |
| 4 | #include "types.h" // container_of |
| 5 | |
| 6 | |
| 7 | /**************************************************************** |
| 8 | * hlist - Double linked lists with a single pointer list head |
| 9 | ****************************************************************/ |
| 10 | |
| 11 | struct hlist_node { |
| 12 | struct hlist_node *next, **pprev; |
| 13 | }; |
| 14 | |
| 15 | struct hlist_head { |
| 16 | struct hlist_node *first; |
| 17 | }; |
| 18 | |
| 19 | static inline int |
| 20 | hlist_empty(const struct hlist_head *h) |
| 21 | { |
| 22 | return !h->first; |
| 23 | } |
| 24 | |
| 25 | static inline void |
| 26 | hlist_del(struct hlist_node *n) |
| 27 | { |
| 28 | struct hlist_node *next = n->next; |
| 29 | struct hlist_node **pprev = n->pprev; |
| 30 | *pprev = next; |
| 31 | if (next) |
| 32 | next->pprev = pprev; |
| 33 | } |
| 34 | |
| 35 | static inline void |
| 36 | hlist_add(struct hlist_node *n, struct hlist_node **pprev) |
| 37 | { |
| 38 | struct hlist_node *next = *pprev; |
| 39 | n->pprev = pprev; |
| 40 | n->next = next; |
| 41 | if (next) |
| 42 | next->pprev = &n->next; |
| 43 | *pprev = n; |
| 44 | } |
| 45 | |
| 46 | static inline void |
| 47 | hlist_add_head(struct hlist_node *n, struct hlist_head *h) |
| 48 | { |
| 49 | hlist_add(n, &h->first); |
| 50 | } |
| 51 | |
| 52 | static inline void |
| 53 | hlist_add_before(struct hlist_node *n, struct hlist_node *next) |
| 54 | { |
| 55 | hlist_add(n, next->pprev); |
| 56 | } |
| 57 | |
| 58 | static inline void |
| 59 | hlist_add_after(struct hlist_node *n, struct hlist_node *prev) |
| 60 | { |
| 61 | hlist_add(n, &prev->next); |
| 62 | } |
| 63 | |
Kevin O'Connor | 7af8d12 | 2015-09-28 22:20:27 -0400 | [diff] [blame] | 64 | static inline void |
| 65 | hlist_replace(struct hlist_node *old, struct hlist_node *new) |
| 66 | { |
| 67 | new->next = old->next; |
| 68 | if (new->next) |
| 69 | new->next->pprev = &new->next; |
| 70 | new->pprev = old->pprev; |
| 71 | *new->pprev = new; |
| 72 | } |
| 73 | |
Kevin O'Connor | e097a75 | 2013-06-08 21:49:12 -0400 | [diff] [blame] | 74 | #define hlist_for_each_entry(pos, head, member) \ |
| 75 | for (pos = container_of((head)->first, typeof(*pos), member) \ |
| 76 | ; pos != container_of(NULL, typeof(*pos), member) \ |
| 77 | ; pos = container_of(pos->member.next, typeof(*pos), member)) |
| 78 | |
Kevin O'Connor | 030a58a | 2013-06-13 21:24:14 -0400 | [diff] [blame] | 79 | #define hlist_for_each_entry_safe(pos, n, head, member) \ |
| 80 | for (pos = container_of((head)->first, typeof(*pos), member) \ |
| 81 | ; pos != container_of(NULL, typeof(*pos), member) \ |
| 82 | && ({ n = pos->member.next; 1; }) \ |
| 83 | ; pos = container_of(n, typeof(*pos), member)) |
| 84 | |
| 85 | #define hlist_for_each_entry_pprev(pos, pprev, head, member) \ |
Kevin O'Connor | e097a75 | 2013-06-08 21:49:12 -0400 | [diff] [blame] | 86 | for (pprev = &(head)->first \ |
Kevin O'Connor | 9539e41 | 2013-06-13 20:44:09 -0400 | [diff] [blame] | 87 | ; *pprev && ({ pos=container_of(*pprev, typeof(*pos), member); 1; }) \ |
Kevin O'Connor | e097a75 | 2013-06-08 21:49:12 -0400 | [diff] [blame] | 88 | ; pprev = &(*pprev)->next) |
| 89 | |
| 90 | |
| 91 | #endif // list.h |