1 /* Public domain. */
2
3 #ifndef _LINUX_LLIST_H
4 #define _LINUX_LLIST_H
5
6 #include <sys/atomic.h>
7
8 struct llist_node {
9 struct llist_node *next;
10 };
11
12 struct llist_head {
13 struct llist_node *first;
14 };
15
16 #define llist_entry(ptr, type, member) container_of(ptr, type, member)
17
18 static inline struct llist_node *
llist_del_all(struct llist_head * head)19 llist_del_all(struct llist_head *head)
20 {
21 return atomic_swap_ptr(&head->first, NULL);
22 }
23
24 static inline struct llist_node *
llist_del_first(struct llist_head * head)25 llist_del_first(struct llist_head *head)
26 {
27 struct llist_node *first, *next;
28
29 do {
30 first = head->first;
31 if (first == NULL)
32 return NULL;
33 next = first->next;
34 } while (atomic_cas_ptr(&head->first, first, next) != first);
35
36 return first;
37 }
38
39 static inline bool
llist_add(struct llist_node * new,struct llist_head * head)40 llist_add(struct llist_node *new, struct llist_head *head)
41 {
42 struct llist_node *first;
43
44 do {
45 new->next = first = head->first;
46 } while (atomic_cas_ptr(&head->first, first, new) != first);
47
48 return (first == NULL);
49 }
50
51 static inline bool
llist_add_batch(struct llist_node * new_first,struct llist_node * new_last,struct llist_head * head)52 llist_add_batch(struct llist_node *new_first, struct llist_node *new_last,
53 struct llist_head *head)
54 {
55 struct llist_node *first;
56
57 do {
58 new_last->next = first = head->first;
59 } while (atomic_cas_ptr(&head->first, first, new_first) != first);
60
61 return (first == NULL);
62 }
63
64 static inline void
init_llist_head(struct llist_head * head)65 init_llist_head(struct llist_head *head)
66 {
67 head->first = NULL;
68 }
69
70 static inline bool
llist_empty(struct llist_head * head)71 llist_empty(struct llist_head *head)
72 {
73 return (head->first == NULL);
74 }
75
76 #define llist_for_each_safe(pos, n, node) \
77 for ((pos) = (node); \
78 (pos) != NULL && \
79 ((n) = (pos)->next, pos); \
80 (pos) = (n))
81
82 #define llist_for_each_entry_safe(pos, n, node, member) \
83 for (pos = llist_entry((node), __typeof(*pos), member); \
84 ((char *)(pos) + offsetof(typeof(*(pos)), member)) != NULL && \
85 (n = llist_entry(pos->member.next, __typeof(*pos), member), pos); \
86 pos = n)
87
88 #define llist_for_each_entry(pos, node, member) \
89 for ((pos) = llist_entry((node), __typeof(*(pos)), member); \
90 ((char *)(pos) + offsetof(typeof(*(pos)), member)) != NULL; \
91 (pos) = llist_entry((pos)->member.next, __typeof(*(pos)), member))
92
93 #endif
94