These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / include / linux / swait.h
1 #ifndef _LINUX_SWAIT_H
2 #define _LINUX_SWAIT_H
3
4 #include <linux/list.h>
5 #include <linux/stddef.h>
6 #include <linux/spinlock.h>
7 #include <asm/current.h>
8
9 /*
10  * Simple wait queues
11  *
12  * While these are very similar to the other/complex wait queues (wait.h) the
13  * most important difference is that the simple waitqueue allows for
14  * deterministic behaviour -- IOW it has strictly bounded IRQ and lock hold
15  * times.
16  *
17  * In order to make this so, we had to drop a fair number of features of the
18  * other waitqueue code; notably:
19  *
20  *  - mixing INTERRUPTIBLE and UNINTERRUPTIBLE sleeps on the same waitqueue;
21  *    all wakeups are TASK_NORMAL in order to avoid O(n) lookups for the right
22  *    sleeper state.
23  *
24  *  - the exclusive mode; because this requires preserving the list order
25  *    and this is hard.
26  *
27  *  - custom wake functions; because you cannot give any guarantees about
28  *    random code.
29  *
30  * As a side effect of this; the data structures are slimmer.
31  *
32  * One would recommend using this wait queue where possible.
33  */
34
35 struct task_struct;
36
37 struct swait_queue_head {
38         raw_spinlock_t          lock;
39         struct list_head        task_list;
40 };
41
42 struct swait_queue {
43         struct task_struct      *task;
44         struct list_head        task_list;
45 };
46
47 #define __SWAITQUEUE_INITIALIZER(name) {                                \
48         .task           = current,                                      \
49         .task_list      = LIST_HEAD_INIT((name).task_list),             \
50 }
51
52 #define DECLARE_SWAITQUEUE(name)                                        \
53         struct swait_queue name = __SWAITQUEUE_INITIALIZER(name)
54
55 #define __SWAIT_QUEUE_HEAD_INITIALIZER(name) {                          \
56         .lock           = __RAW_SPIN_LOCK_UNLOCKED(name.lock),          \
57         .task_list      = LIST_HEAD_INIT((name).task_list),             \
58 }
59
60 #define DECLARE_SWAIT_QUEUE_HEAD(name)                                  \
61         struct swait_queue_head name = __SWAIT_QUEUE_HEAD_INITIALIZER(name)
62
63 extern void __init_swait_queue_head(struct swait_queue_head *q, const char *name,
64                                     struct lock_class_key *key);
65
66 #define init_swait_queue_head(q)                                \
67         do {                                                    \
68                 static struct lock_class_key __key;             \
69                 __init_swait_queue_head((q), #q, &__key);       \
70         } while (0)
71
72 #ifdef CONFIG_LOCKDEP
73 # define __SWAIT_QUEUE_HEAD_INIT_ONSTACK(name)                  \
74         ({ init_swait_queue_head(&name); name; })
75 # define DECLARE_SWAIT_QUEUE_HEAD_ONSTACK(name)                 \
76         struct swait_queue_head name = __SWAIT_QUEUE_HEAD_INIT_ONSTACK(name)
77 #else
78 # define DECLARE_SWAIT_QUEUE_HEAD_ONSTACK(name)                 \
79         DECLARE_SWAIT_QUEUE_HEAD(name)
80 #endif
81
82 static inline int swait_active(struct swait_queue_head *q)
83 {
84         return !list_empty(&q->task_list);
85 }
86
87 extern void swake_up(struct swait_queue_head *q);
88 extern void swake_up_all(struct swait_queue_head *q);
89 extern void swake_up_locked(struct swait_queue_head *q);
90 extern void swake_up_all_locked(struct swait_queue_head *q);
91
92 extern void __prepare_to_swait(struct swait_queue_head *q, struct swait_queue *wait);
93 extern void prepare_to_swait(struct swait_queue_head *q, struct swait_queue *wait, int state);
94 extern long prepare_to_swait_event(struct swait_queue_head *q, struct swait_queue *wait, int state);
95
96 extern void __finish_swait(struct swait_queue_head *q, struct swait_queue *wait);
97 extern void finish_swait(struct swait_queue_head *q, struct swait_queue *wait);
98
99 /* as per ___wait_event() but for swait, therefore "exclusive == 0" */
100 #define ___swait_event(wq, condition, state, ret, cmd)                  \
101 ({                                                                      \
102         struct swait_queue __wait;                                      \
103         long __ret = ret;                                               \
104                                                                         \
105         INIT_LIST_HEAD(&__wait.task_list);                              \
106         for (;;) {                                                      \
107                 long __int = prepare_to_swait_event(&wq, &__wait, state);\
108                                                                         \
109                 if (condition)                                          \
110                         break;                                          \
111                                                                         \
112                 if (___wait_is_interruptible(state) && __int) {         \
113                         __ret = __int;                                  \
114                         break;                                          \
115                 }                                                       \
116                                                                         \
117                 cmd;                                                    \
118         }                                                               \
119         finish_swait(&wq, &__wait);                                     \
120         __ret;                                                          \
121 })
122
123 #define __swait_event(wq, condition)                                    \
124         (void)___swait_event(wq, condition, TASK_UNINTERRUPTIBLE, 0,    \
125                             schedule())
126
127 #define swait_event(wq, condition)                                      \
128 do {                                                                    \
129         if (condition)                                                  \
130                 break;                                                  \
131         __swait_event(wq, condition);                                   \
132 } while (0)
133
134 #define __swait_event_timeout(wq, condition, timeout)                   \
135         ___swait_event(wq, ___wait_cond_timeout(condition),             \
136                       TASK_UNINTERRUPTIBLE, timeout,                    \
137                       __ret = schedule_timeout(__ret))
138
139 #define swait_event_timeout(wq, condition, timeout)                     \
140 ({                                                                      \
141         long __ret = timeout;                                           \
142         if (!___wait_cond_timeout(condition))                           \
143                 __ret = __swait_event_timeout(wq, condition, timeout);  \
144         __ret;                                                          \
145 })
146
147 #define __swait_event_interruptible(wq, condition)                      \
148         ___swait_event(wq, condition, TASK_INTERRUPTIBLE, 0,            \
149                       schedule())
150
151 #define swait_event_interruptible(wq, condition)                        \
152 ({                                                                      \
153         int __ret = 0;                                                  \
154         if (!(condition))                                               \
155                 __ret = __swait_event_interruptible(wq, condition);     \
156         __ret;                                                          \
157 })
158
159 #define __swait_event_interruptible_timeout(wq, condition, timeout)     \
160         ___swait_event(wq, ___wait_cond_timeout(condition),             \
161                       TASK_INTERRUPTIBLE, timeout,                      \
162                       __ret = schedule_timeout(__ret))
163
164 #define swait_event_interruptible_timeout(wq, condition, timeout)       \
165 ({                                                                      \
166         long __ret = timeout;                                           \
167         if (!___wait_cond_timeout(condition))                           \
168                 __ret = __swait_event_interruptible_timeout(wq,         \
169                                                 condition, timeout);    \
170         __ret;                                                          \
171 })
172
173 #endif /* _LINUX_SWAIT_H */