]> git.sesse.net Git - bcachefs-tools-debian/blob - include/linux/wait.h
Delete more unused shim code, update bcache code
[bcachefs-tools-debian] / include / linux / wait.h
1 #ifndef _LINUX_WAIT_H
2 #define _LINUX_WAIT_H
3
4 #include <pthread.h>
5 #include <linux/bitmap.h>
6 #include <linux/list.h>
7 #include <linux/spinlock.h>
8
9 typedef struct __wait_queue wait_queue_t;
10 typedef int (*wait_queue_func_t)(wait_queue_t *wait, unsigned mode, int flags, void *key);
11
12 #define WQ_FLAG_EXCLUSIVE       0x01
13
14 struct __wait_queue {
15         unsigned int            flags;
16         void                    *private;
17         wait_queue_func_t       func;
18         struct list_head        task_list;
19 };
20
21 typedef struct {
22         spinlock_t              lock;
23         struct list_head        task_list;
24 } wait_queue_head_t;
25
26 void wake_up(wait_queue_head_t *);
27 void prepare_to_wait(wait_queue_head_t *q, wait_queue_t *wait, int state);
28 void finish_wait(wait_queue_head_t *q, wait_queue_t *wait);
29 int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key);
30 int default_wake_function(wait_queue_t *wait, unsigned mode, int flags, void *key);
31
32 #define DECLARE_WAITQUEUE(name, tsk)                                    \
33         wait_queue_t name = {                                           \
34                 .private        = tsk,                                  \
35                 .func           = default_wake_function,                \
36                 .task_list      = { NULL, NULL }                        \
37         }
38
39 #define __WAIT_QUEUE_HEAD_INITIALIZER(name) {                           \
40         .lock           = __SPIN_LOCK_UNLOCKED(name.lock),              \
41         .task_list      = { &(name).task_list, &(name).task_list } }
42
43 #define DECLARE_WAIT_QUEUE_HEAD(name) \
44         wait_queue_head_t name = __WAIT_QUEUE_HEAD_INITIALIZER(name)
45
46 static inline void init_waitqueue_head(wait_queue_head_t *q)
47 {
48         spin_lock_init(&q->lock);
49         INIT_LIST_HEAD(&q->task_list);
50 }
51
52 #define DEFINE_WAIT(name)                                               \
53         wait_queue_t name = {                                           \
54                 .private        = current,                              \
55                 .func           = autoremove_wake_function,             \
56                 .task_list      = LIST_HEAD_INIT((name).task_list),     \
57         }
58
59 #define ___wait_cond_timeout(condition)                                 \
60 ({                                                                      \
61         bool __cond = (condition);                                      \
62         if (__cond && !__ret)                                           \
63                 __ret = 1;                                              \
64         __cond || !__ret;                                               \
65 })
66
67 #define ___wait_event(wq, condition, state, exclusive, ret, cmd)        \
68 ({                                                                      \
69         DEFINE_WAIT(__wait);                                            \
70         long __ret = ret;                                               \
71                                                                         \
72         for (;;) {                                                      \
73                 prepare_to_wait(&wq, &__wait, state);                   \
74                 if (condition)                                          \
75                         break;                                          \
76                 cmd;                                                    \
77         }                                                               \
78         finish_wait(&wq, &__wait);                                      \
79         __ret;                                                          \
80 })
81
82 #define __wait_event(wq, condition)                                     \
83         (void)___wait_event(wq, condition, TASK_UNINTERRUPTIBLE, 0, 0,  \
84                             schedule())
85
86 #define wait_event(wq, condition)                                       \
87 do {                                                                    \
88         if (condition)                                                  \
89                 break;                                                  \
90         __wait_event(wq, condition);                                    \
91 } while (0)
92
93 #define __wait_event_timeout(wq, condition, timeout)                    \
94         ___wait_event(wq, ___wait_cond_timeout(condition),              \
95                       TASK_UNINTERRUPTIBLE, 0, timeout,                 \
96                       __ret = schedule_timeout(__ret))
97
98 #define wait_event_timeout(wq, condition, timeout)                      \
99 ({                                                                      \
100         long __ret = timeout;                                           \
101         if (!___wait_cond_timeout(condition))                           \
102                 __ret = __wait_event_timeout(wq, condition, timeout);   \
103         __ret;                                                          \
104 })
105
106 void wake_up_bit(void *, int);
107 void __wait_on_bit(void *, int, unsigned);
108 void __wait_on_bit_lock(void *, int, unsigned);
109
110 static inline int
111 wait_on_bit(unsigned long *word, int bit, unsigned mode)
112 {
113         if (!test_bit(bit, word))
114                 return 0;
115         __wait_on_bit(word, bit, mode);
116         return 0;
117 }
118
119 static inline int
120 wait_on_bit_lock(unsigned long *word, int bit, unsigned mode)
121 {
122         if (!test_and_set_bit(bit, word))
123                 return 0;
124         __wait_on_bit_lock(word, bit, mode);
125         return 0;
126 }
127
128 #define wait_on_bit_io(w, b, m)                 wait_on_bit(w, b, m)
129 #define wait_on_bit_lock_io(w, b, m)            wait_on_bit_lock(w, b, m)
130
131 #endif /* _LINUX_WAIT_H */