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 void 53 init_llist_head(struct llist_head *head) 54 { 55 head->first = NULL; 56 } 57 58 static inline bool 59 llist_empty(struct llist_head *head) 60 { 61 return (head->first == NULL); 62 } 63 64 #define llist_for_each_entry_safe(pos, n, node, member) \ 65 for (pos = llist_entry((node), __typeof(*pos), member); \ 66 pos != NULL && \ 67 (n = llist_entry(pos->member.next, __typeof(*pos), member), pos); \ 68 pos = n) 69 70 #endif 71