| #ifndef INTERNAL_IO_SLIST_H | 
 | #define INTERNAL_IO_SLIST_H | 
 |  | 
 | #include <linux/io_uring_types.h> | 
 |  | 
 | #define wq_list_for_each(pos, prv, head)			\ | 
 | 	for (pos = (head)->first, prv = NULL; pos; prv = pos, pos = (pos)->next) | 
 |  | 
 | #define wq_list_for_each_resume(pos, prv)			\ | 
 | 	for (; pos; prv = pos, pos = (pos)->next) | 
 |  | 
 | #define wq_list_empty(list)	(READ_ONCE((list)->first) == NULL) | 
 |  | 
 | #define INIT_WQ_LIST(list)	do {				\ | 
 | 	(list)->first = NULL;					\ | 
 | } while (0) | 
 |  | 
 | static inline void wq_list_add_after(struct io_wq_work_node *node, | 
 | 				     struct io_wq_work_node *pos, | 
 | 				     struct io_wq_work_list *list) | 
 | { | 
 | 	struct io_wq_work_node *next = pos->next; | 
 |  | 
 | 	pos->next = node; | 
 | 	node->next = next; | 
 | 	if (!next) | 
 | 		list->last = node; | 
 | } | 
 |  | 
 | /** | 
 |  * wq_list_merge - merge the second list to the first one. | 
 |  * @list0: the first list | 
 |  * @list1: the second list | 
 |  * Return the first node after mergence. | 
 |  */ | 
 | static inline struct io_wq_work_node *wq_list_merge(struct io_wq_work_list *list0, | 
 | 						    struct io_wq_work_list *list1) | 
 | { | 
 | 	struct io_wq_work_node *ret; | 
 |  | 
 | 	if (!list0->first) { | 
 | 		ret = list1->first; | 
 | 	} else { | 
 | 		ret = list0->first; | 
 | 		list0->last->next = list1->first; | 
 | 	} | 
 | 	INIT_WQ_LIST(list0); | 
 | 	INIT_WQ_LIST(list1); | 
 | 	return ret; | 
 | } | 
 |  | 
 | static inline void wq_list_add_tail(struct io_wq_work_node *node, | 
 | 				    struct io_wq_work_list *list) | 
 | { | 
 | 	node->next = NULL; | 
 | 	if (!list->first) { | 
 | 		list->last = node; | 
 | 		WRITE_ONCE(list->first, node); | 
 | 	} else { | 
 | 		list->last->next = node; | 
 | 		list->last = node; | 
 | 	} | 
 | } | 
 |  | 
 | static inline void wq_list_add_head(struct io_wq_work_node *node, | 
 | 				    struct io_wq_work_list *list) | 
 | { | 
 | 	node->next = list->first; | 
 | 	if (!node->next) | 
 | 		list->last = node; | 
 | 	WRITE_ONCE(list->first, node); | 
 | } | 
 |  | 
 | static inline void wq_list_cut(struct io_wq_work_list *list, | 
 | 			       struct io_wq_work_node *last, | 
 | 			       struct io_wq_work_node *prev) | 
 | { | 
 | 	/* first in the list, if prev==NULL */ | 
 | 	if (!prev) | 
 | 		WRITE_ONCE(list->first, last->next); | 
 | 	else | 
 | 		prev->next = last->next; | 
 |  | 
 | 	if (last == list->last) | 
 | 		list->last = prev; | 
 | 	last->next = NULL; | 
 | } | 
 |  | 
 | static inline void __wq_list_splice(struct io_wq_work_list *list, | 
 | 				    struct io_wq_work_node *to) | 
 | { | 
 | 	list->last->next = to->next; | 
 | 	to->next = list->first; | 
 | 	INIT_WQ_LIST(list); | 
 | } | 
 |  | 
 | static inline bool wq_list_splice(struct io_wq_work_list *list, | 
 | 				  struct io_wq_work_node *to) | 
 | { | 
 | 	if (!wq_list_empty(list)) { | 
 | 		__wq_list_splice(list, to); | 
 | 		return true; | 
 | 	} | 
 | 	return false; | 
 | } | 
 |  | 
 | static inline void wq_stack_add_head(struct io_wq_work_node *node, | 
 | 				     struct io_wq_work_node *stack) | 
 | { | 
 | 	node->next = stack->next; | 
 | 	stack->next = node; | 
 | } | 
 |  | 
 | static inline void wq_list_del(struct io_wq_work_list *list, | 
 | 			       struct io_wq_work_node *node, | 
 | 			       struct io_wq_work_node *prev) | 
 | { | 
 | 	wq_list_cut(list, node, prev); | 
 | } | 
 |  | 
 | static inline | 
 | struct io_wq_work_node *wq_stack_extract(struct io_wq_work_node *stack) | 
 | { | 
 | 	struct io_wq_work_node *node = stack->next; | 
 |  | 
 | 	stack->next = node->next; | 
 | 	return node; | 
 | } | 
 |  | 
 | static inline struct io_wq_work *wq_next_work(struct io_wq_work *work) | 
 | { | 
 | 	if (!work->list.next) | 
 | 		return NULL; | 
 |  | 
 | 	return container_of(work->list.next, struct io_wq_work, list); | 
 | } | 
 |  | 
 | #endif // INTERNAL_IO_SLIST_H |