Commit | Line | Data |
---|---|---|
a6b21fbb PB |
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 | struct io_wq_work_node *next = pos->next; | |
23 | ||
24 | pos->next = node; | |
25 | node->next = next; | |
26 | if (!next) | |
27 | list->last = node; | |
28 | } | |
29 | ||
30 | /** | |
31 | * wq_list_merge - merge the second list to the first one. | |
32 | * @list0: the first list | |
33 | * @list1: the second list | |
34 | * Return the first node after mergence. | |
35 | */ | |
36 | static inline struct io_wq_work_node *wq_list_merge(struct io_wq_work_list *list0, | |
37 | struct io_wq_work_list *list1) | |
38 | { | |
39 | struct io_wq_work_node *ret; | |
40 | ||
41 | if (!list0->first) { | |
42 | ret = list1->first; | |
43 | } else { | |
44 | ret = list0->first; | |
45 | list0->last->next = list1->first; | |
46 | } | |
47 | INIT_WQ_LIST(list0); | |
48 | INIT_WQ_LIST(list1); | |
49 | return ret; | |
50 | } | |
51 | ||
52 | static inline void wq_list_add_tail(struct io_wq_work_node *node, | |
53 | struct io_wq_work_list *list) | |
54 | { | |
55 | node->next = NULL; | |
56 | if (!list->first) { | |
57 | list->last = node; | |
58 | WRITE_ONCE(list->first, node); | |
59 | } else { | |
60 | list->last->next = node; | |
61 | list->last = node; | |
62 | } | |
63 | } | |
64 | ||
65 | static inline void wq_list_add_head(struct io_wq_work_node *node, | |
66 | struct io_wq_work_list *list) | |
67 | { | |
68 | node->next = list->first; | |
69 | if (!node->next) | |
70 | list->last = node; | |
71 | WRITE_ONCE(list->first, node); | |
72 | } | |
73 | ||
74 | static inline void wq_list_cut(struct io_wq_work_list *list, | |
75 | struct io_wq_work_node *last, | |
76 | struct io_wq_work_node *prev) | |
77 | { | |
78 | /* first in the list, if prev==NULL */ | |
79 | if (!prev) | |
80 | WRITE_ONCE(list->first, last->next); | |
81 | else | |
82 | prev->next = last->next; | |
83 | ||
84 | if (last == list->last) | |
85 | list->last = prev; | |
86 | last->next = NULL; | |
87 | } | |
88 | ||
89 | static inline void __wq_list_splice(struct io_wq_work_list *list, | |
90 | struct io_wq_work_node *to) | |
91 | { | |
92 | list->last->next = to->next; | |
93 | to->next = list->first; | |
94 | INIT_WQ_LIST(list); | |
95 | } | |
96 | ||
97 | static inline bool wq_list_splice(struct io_wq_work_list *list, | |
98 | struct io_wq_work_node *to) | |
99 | { | |
100 | if (!wq_list_empty(list)) { | |
101 | __wq_list_splice(list, to); | |
102 | return true; | |
103 | } | |
104 | return false; | |
105 | } | |
106 | ||
107 | static inline void wq_stack_add_head(struct io_wq_work_node *node, | |
108 | struct io_wq_work_node *stack) | |
109 | { | |
110 | node->next = stack->next; | |
111 | stack->next = node; | |
112 | } | |
113 | ||
114 | static inline void wq_list_del(struct io_wq_work_list *list, | |
115 | struct io_wq_work_node *node, | |
116 | struct io_wq_work_node *prev) | |
117 | { | |
118 | wq_list_cut(list, node, prev); | |
119 | } | |
120 | ||
121 | static inline | |
122 | struct io_wq_work_node *wq_stack_extract(struct io_wq_work_node *stack) | |
123 | { | |
124 | struct io_wq_work_node *node = stack->next; | |
125 | ||
126 | stack->next = node->next; | |
127 | return node; | |
128 | } | |
129 | ||
130 | static inline struct io_wq_work *wq_next_work(struct io_wq_work *work) | |
131 | { | |
132 | if (!work->list.next) | |
133 | return NULL; | |
134 | ||
135 | return container_of(work->list.next, struct io_wq_work, list); | |
136 | } | |
137 | ||
138 | #endif // INTERNAL_IO_SLIST_H |