xref: /linux/io_uring/slist.h (revision 69050f8d6d075dc01af7a5f2f550a8067510366f)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef INTERNAL_IO_SLIST_H
3 #define INTERNAL_IO_SLIST_H
4 
5 #include <linux/io_uring_types.h>
6 
7 #define __wq_list_for_each(pos, head)				\
8 	for (pos = (head)->first; pos; pos = (pos)->next)
9 
10 #define wq_list_for_each(pos, prv, head)			\
11 	for (pos = (head)->first, prv = NULL; pos; prv = pos, pos = (pos)->next)
12 
13 #define wq_list_empty(list)	(READ_ONCE((list)->first) == NULL)
14 
15 #define INIT_WQ_LIST(list)	do {				\
16 	(list)->first = NULL;					\
17 } while (0)
18 
19 static inline void wq_list_add_after(struct io_wq_work_node *node,
20 				     struct io_wq_work_node *pos,
21 				     struct io_wq_work_list *list)
22 {
23 	struct io_wq_work_node *next = pos->next;
24 
25 	pos->next = node;
26 	node->next = next;
27 	if (!next)
28 		list->last = node;
29 }
30 
31 static inline void wq_list_add_tail(struct io_wq_work_node *node,
32 				    struct io_wq_work_list *list)
33 {
34 	node->next = NULL;
35 	if (!list->first) {
36 		list->last = node;
37 		WRITE_ONCE(list->first, node);
38 	} else {
39 		list->last->next = node;
40 		list->last = node;
41 	}
42 }
43 
44 static inline void wq_list_cut(struct io_wq_work_list *list,
45 			       struct io_wq_work_node *last,
46 			       struct io_wq_work_node *prev)
47 {
48 	/* first in the list, if prev==NULL */
49 	if (!prev)
50 		WRITE_ONCE(list->first, last->next);
51 	else
52 		prev->next = last->next;
53 
54 	if (last == list->last)
55 		list->last = prev;
56 	last->next = NULL;
57 }
58 
59 static inline void wq_stack_add_head(struct io_wq_work_node *node,
60 				     struct io_wq_work_node *stack)
61 {
62 	node->next = stack->next;
63 	stack->next = node;
64 }
65 
66 static inline void wq_list_del(struct io_wq_work_list *list,
67 			       struct io_wq_work_node *node,
68 			       struct io_wq_work_node *prev)
69 {
70 	wq_list_cut(list, node, prev);
71 }
72 
73 static inline
74 struct io_wq_work_node *wq_stack_extract(struct io_wq_work_node *stack)
75 {
76 	struct io_wq_work_node *node = stack->next;
77 
78 	stack->next = node->next;
79 	return node;
80 }
81 
82 static inline struct io_wq_work *wq_next_work(struct io_wq_work *work)
83 {
84 	if (!work->list.next)
85 		return NULL;
86 
87 	return container_of(work->list.next, struct io_wq_work, list);
88 }
89 
90 #endif // INTERNAL_IO_SLIST_H
91