Line data Source code
1 : #ifndef INTERNAL_IO_SLIST_H 2 : #define INTERNAL_IO_SLIST_H 3 : 4 : #include <linux/io_uring_types.h> 5 : 6 : #define __wq_list_for_each(pos, head) \ 7 : for (pos = (head)->first; pos; pos = (pos)->next) 8 : 9 : #define wq_list_for_each(pos, prv, head) \ 10 : for (pos = (head)->first, prv = NULL; pos; prv = pos, pos = (pos)->next) 11 : 12 : #define wq_list_for_each_resume(pos, prv) \ 13 : for (; pos; prv = pos, pos = (pos)->next) 14 : 15 : #define wq_list_empty(list) (READ_ONCE((list)->first) == NULL) 16 : 17 : #define INIT_WQ_LIST(list) do { \ 18 : (list)->first = NULL; \ 19 : } while (0) 20 : 21 : static inline void wq_list_add_after(struct io_wq_work_node *node, 22 : struct io_wq_work_node *pos, 23 : struct io_wq_work_list *list) 24 : { 25 0 : struct io_wq_work_node *next = pos->next; 26 : 27 0 : pos->next = node; 28 0 : node->next = next; 29 0 : if (!next) 30 0 : list->last = node; 31 : } 32 : 33 : static inline void wq_list_add_tail(struct io_wq_work_node *node, 34 : struct io_wq_work_list *list) 35 : { 36 0 : node->next = NULL; 37 0 : if (!list->first) { 38 0 : list->last = node; 39 0 : WRITE_ONCE(list->first, node); 40 : } else { 41 0 : list->last->next = node; 42 0 : list->last = node; 43 : } 44 : } 45 : 46 : static inline void wq_list_add_head(struct io_wq_work_node *node, 47 : struct io_wq_work_list *list) 48 : { 49 0 : node->next = list->first; 50 0 : if (!node->next) 51 0 : list->last = node; 52 0 : WRITE_ONCE(list->first, node); 53 : } 54 : 55 : static inline void wq_list_cut(struct io_wq_work_list *list, 56 : struct io_wq_work_node *last, 57 : struct io_wq_work_node *prev) 58 : { 59 : /* first in the list, if prev==NULL */ 60 0 : if (!prev) 61 0 : WRITE_ONCE(list->first, last->next); 62 : else 63 0 : prev->next = last->next; 64 : 65 0 : if (last == list->last) 66 0 : list->last = prev; 67 0 : last->next = NULL; 68 : } 69 : 70 : static inline void __wq_list_splice(struct io_wq_work_list *list, 71 : struct io_wq_work_node *to) 72 : { 73 0 : list->last->next = to->next; 74 0 : to->next = list->first; 75 0 : INIT_WQ_LIST(list); 76 : } 77 : 78 : static inline bool wq_list_splice(struct io_wq_work_list *list, 79 : struct io_wq_work_node *to) 80 : { 81 0 : if (!wq_list_empty(list)) { 82 0 : __wq_list_splice(list, to); 83 : return true; 84 : } 85 : return false; 86 : } 87 : 88 : static inline void wq_stack_add_head(struct io_wq_work_node *node, 89 : struct io_wq_work_node *stack) 90 : { 91 0 : node->next = stack->next; 92 0 : stack->next = node; 93 : } 94 : 95 : static inline void wq_list_del(struct io_wq_work_list *list, 96 : struct io_wq_work_node *node, 97 : struct io_wq_work_node *prev) 98 : { 99 0 : wq_list_cut(list, node, prev); 100 : } 101 : 102 : static inline 103 : struct io_wq_work_node *wq_stack_extract(struct io_wq_work_node *stack) 104 : { 105 0 : struct io_wq_work_node *node = stack->next; 106 : 107 0 : stack->next = node->next; 108 : return node; 109 : } 110 : 111 : static inline struct io_wq_work *wq_next_work(struct io_wq_work *work) 112 : { 113 0 : if (!work->list.next) 114 : return NULL; 115 : 116 0 : return container_of(work->list.next, struct io_wq_work, list); 117 : } 118 : 119 : #endif // INTERNAL_IO_SLIST_H