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