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) \ 17 ((ptr) ? container_of(ptr, type, member) : NULL) 18 19 static inline struct llist_node * 20 llist_del_all(struct llist_head *head) 21 { 22 return atomic_swap_ptr(&head->first, NULL); 23 } 24 25 static inline struct llist_node * 26 llist_del_first(struct llist_head *head) 27 { 28 struct llist_node *first, *next; 29 30 do { 31 first = head->first; 32 if (first == NULL) 33 return NULL; 34 next = first->next; 35 } while (atomic_cas_ptr(&head->first, first, next) != first); 36 37 return first; 38 } 39 40 static inline bool 41 llist_add(struct llist_node *new, struct llist_head *head) 42 { 43 struct llist_node *first; 44 45 do { 46 new->next = first = head->first; 47 } while (atomic_cas_ptr(&head->first, first, new) != first); 48 49 return (first == NULL); 50 } 51 52 static inline bool 53 llist_add_batch(struct llist_node *new_first, struct llist_node *new_last, 54 struct llist_head *head) 55 { 56 struct llist_node *first; 57 58 do { 59 new_last->next = first = head->first; 60 } while (atomic_cas_ptr(&head->first, first, new_first) != first); 61 62 return (first == NULL); 63 } 64 65 static inline void 66 init_llist_head(struct llist_head *head) 67 { 68 head->first = NULL; 69 } 70 71 static inline bool 72 llist_empty(struct llist_head *head) 73 { 74 return (head->first == NULL); 75 } 76 77 #define llist_for_each_safe(pos, n, node) \ 78 for ((pos) = (node); \ 79 (pos) != NULL && \ 80 ((n) = (pos)->next, pos); \ 81 (pos) = (n)) 82 83 #define llist_for_each_entry_safe(pos, n, node, member) \ 84 for (pos = llist_entry((node), __typeof(*pos), member); \ 85 pos != NULL && \ 86 (n = llist_entry(pos->member.next, __typeof(*pos), member), pos); \ 87 pos = n) 88 89 #define llist_for_each_entry(pos, node, member) \ 90 for ((pos) = llist_entry((node), __typeof(*(pos)), member); \ 91 (pos) != NULL; \ 92 (pos) = llist_entry((pos)->member.next, __typeof(*(pos)), member)) 93 94 #endif 95