| /* SPDX-License-Identifier: GPL-2.0 */ | |
| #ifndef INTERNAL_IO_SLIST_H | |
| #define INTERNAL_IO_SLIST_H | |
| #include <linux/io_uring_types.h> | |
| #define __wq_list_for_each(pos, head) \ | |
| for (pos = (head)->first; pos; pos = (pos)->next) | |
| #define wq_list_for_each(pos, prv, head) \ | |
| for (pos = (head)->first, prv = NULL; 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; | |
| } | |
| 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_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_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 |