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 * 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 * 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 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 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 65 init_llist_head(struct llist_head *head) 66 { 67 head->first = NULL; 68 } 69 70 static inline bool 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