]>
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 | ||
fa780334 JA |
6 | #define __wq_list_for_each(pos, head) \ |
7 | for (pos = (head)->first; pos; pos = (pos)->next) | |
8 | ||
a6b21fbb PB |
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 | struct io_wq_work_node *next = pos->next; | |
26 | ||
27 | pos->next = node; | |
28 | node->next = next; | |
29 | if (!next) | |
30 | list->last = node; | |
31 | } | |
32 | ||
a6b21fbb PB |
33 | static inline void wq_list_add_tail(struct io_wq_work_node *node, |
34 | struct io_wq_work_list *list) | |
35 | { | |
36 | node->next = NULL; | |
37 | if (!list->first) { | |
38 | list->last = node; | |
39 | WRITE_ONCE(list->first, node); | |
40 | } else { | |
41 | list->last->next = node; | |
42 | 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 | node->next = list->first; | |
50 | if (!node->next) | |
51 | list->last = node; | |
52 | 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 | if (!prev) | |
61 | WRITE_ONCE(list->first, last->next); | |
62 | else | |
63 | prev->next = last->next; | |
64 | ||
65 | if (last == list->last) | |
66 | list->last = prev; | |
67 | 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 | list->last->next = to->next; | |
74 | to->next = list->first; | |
75 | 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 | if (!wq_list_empty(list)) { | |
82 | __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 | node->next = stack->next; | |
92 | 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 | 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 | struct io_wq_work_node *node = stack->next; | |
106 | ||
107 | 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 | if (!work->list.next) | |
114 | return NULL; | |
115 | ||
116 | return container_of(work->list.next, struct io_wq_work, list); | |
117 | } | |
118 | ||
fa780334 | 119 | #endif // INTERNAL_IO_SLIST_H |