blob: 94512e306d8cbf6bfcc2063b222a1f2b65302e83 [file] [log] [blame]
Kevin O'Connore097a752013-06-08 21:49:12 -04001#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
11struct hlist_node {
12 struct hlist_node *next, **pprev;
13};
14
15struct hlist_head {
16 struct hlist_node *first;
17};
18
19static inline int
20hlist_empty(const struct hlist_head *h)
21{
22 return !h->first;
23}
24
25static inline void
26hlist_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
35static inline void
36hlist_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
46static inline void
47hlist_add_head(struct hlist_node *n, struct hlist_head *h)
48{
49 hlist_add(n, &h->first);
50}
51
52static inline void
53hlist_add_before(struct hlist_node *n, struct hlist_node *next)
54{
55 hlist_add(n, next->pprev);
56}
57
58static inline void
59hlist_add_after(struct hlist_node *n, struct hlist_node *prev)
60{
61 hlist_add(n, &prev->next);
62}
63
Kevin O'Connor7af8d122015-09-28 22:20:27 -040064static inline void
65hlist_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'Connore097a752013-06-08 21:49:12 -040074#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'Connor030a58a2013-06-13 21:24:14 -040079#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'Connore097a752013-06-08 21:49:12 -040086 for (pprev = &(head)->first \
Kevin O'Connor9539e412013-06-13 20:44:09 -040087 ; *pprev && ({ pos=container_of(*pprev, typeof(*pos), member); 1; }) \
Kevin O'Connore097a752013-06-08 21:49:12 -040088 ; pprev = &(*pprev)->next)
89
90
91#endif // list.h