Back to home page

OSCL-LXR

 
 

    


0001 #ifndef INTERNAL_IO_SLIST_H
0002 #define INTERNAL_IO_SLIST_H
0003 
0004 #include <linux/io_uring_types.h>
0005 
0006 #define wq_list_for_each(pos, prv, head)            \
0007     for (pos = (head)->first, prv = NULL; pos; prv = pos, pos = (pos)->next)
0008 
0009 #define wq_list_for_each_resume(pos, prv)           \
0010     for (; pos; prv = pos, pos = (pos)->next)
0011 
0012 #define wq_list_empty(list) (READ_ONCE((list)->first) == NULL)
0013 
0014 #define INIT_WQ_LIST(list)  do {                \
0015     (list)->first = NULL;                   \
0016 } while (0)
0017 
0018 static inline void wq_list_add_after(struct io_wq_work_node *node,
0019                      struct io_wq_work_node *pos,
0020                      struct io_wq_work_list *list)
0021 {
0022     struct io_wq_work_node *next = pos->next;
0023 
0024     pos->next = node;
0025     node->next = next;
0026     if (!next)
0027         list->last = node;
0028 }
0029 
0030 /**
0031  * wq_list_merge - merge the second list to the first one.
0032  * @list0: the first list
0033  * @list1: the second list
0034  * Return the first node after mergence.
0035  */
0036 static inline struct io_wq_work_node *wq_list_merge(struct io_wq_work_list *list0,
0037                             struct io_wq_work_list *list1)
0038 {
0039     struct io_wq_work_node *ret;
0040 
0041     if (!list0->first) {
0042         ret = list1->first;
0043     } else {
0044         ret = list0->first;
0045         list0->last->next = list1->first;
0046     }
0047     INIT_WQ_LIST(list0);
0048     INIT_WQ_LIST(list1);
0049     return ret;
0050 }
0051 
0052 static inline void wq_list_add_tail(struct io_wq_work_node *node,
0053                     struct io_wq_work_list *list)
0054 {
0055     node->next = NULL;
0056     if (!list->first) {
0057         list->last = node;
0058         WRITE_ONCE(list->first, node);
0059     } else {
0060         list->last->next = node;
0061         list->last = node;
0062     }
0063 }
0064 
0065 static inline void wq_list_add_head(struct io_wq_work_node *node,
0066                     struct io_wq_work_list *list)
0067 {
0068     node->next = list->first;
0069     if (!node->next)
0070         list->last = node;
0071     WRITE_ONCE(list->first, node);
0072 }
0073 
0074 static inline void wq_list_cut(struct io_wq_work_list *list,
0075                    struct io_wq_work_node *last,
0076                    struct io_wq_work_node *prev)
0077 {
0078     /* first in the list, if prev==NULL */
0079     if (!prev)
0080         WRITE_ONCE(list->first, last->next);
0081     else
0082         prev->next = last->next;
0083 
0084     if (last == list->last)
0085         list->last = prev;
0086     last->next = NULL;
0087 }
0088 
0089 static inline void __wq_list_splice(struct io_wq_work_list *list,
0090                     struct io_wq_work_node *to)
0091 {
0092     list->last->next = to->next;
0093     to->next = list->first;
0094     INIT_WQ_LIST(list);
0095 }
0096 
0097 static inline bool wq_list_splice(struct io_wq_work_list *list,
0098                   struct io_wq_work_node *to)
0099 {
0100     if (!wq_list_empty(list)) {
0101         __wq_list_splice(list, to);
0102         return true;
0103     }
0104     return false;
0105 }
0106 
0107 static inline void wq_stack_add_head(struct io_wq_work_node *node,
0108                      struct io_wq_work_node *stack)
0109 {
0110     node->next = stack->next;
0111     stack->next = node;
0112 }
0113 
0114 static inline void wq_list_del(struct io_wq_work_list *list,
0115                    struct io_wq_work_node *node,
0116                    struct io_wq_work_node *prev)
0117 {
0118     wq_list_cut(list, node, prev);
0119 }
0120 
0121 static inline
0122 struct io_wq_work_node *wq_stack_extract(struct io_wq_work_node *stack)
0123 {
0124     struct io_wq_work_node *node = stack->next;
0125 
0126     stack->next = node->next;
0127     return node;
0128 }
0129 
0130 static inline struct io_wq_work *wq_next_work(struct io_wq_work *work)
0131 {
0132     if (!work->list.next)
0133         return NULL;
0134 
0135     return container_of(work->list.next, struct io_wq_work, list);
0136 }
0137 
0138 #endif // INTERNAL_IO_SLIST_H