]> rtime.felk.cvut.cz Git - zynq/linux.git/blob - include/linux/wait-simple.h
4efba4d28c48ae434a032f0684b7cbccfe07ad9f
[zynq/linux.git] / include / linux / wait-simple.h
1 #ifndef _LINUX_WAIT_SIMPLE_H
2 #define _LINUX_WAIT_SIMPLE_H
3
4 #include <linux/spinlock.h>
5 #include <linux/list.h>
6
7 #include <asm/current.h>
8
9 struct swaiter {
10         struct task_struct      *task;
11         struct list_head        node;
12 };
13
14 #define DEFINE_SWAITER(name)                                    \
15         struct swaiter name = {                                 \
16                 .task   = current,                              \
17                 .node   = LIST_HEAD_INIT((name).node),          \
18         }
19
20 struct swait_head {
21         raw_spinlock_t          lock;
22         struct list_head        list;
23 };
24
25 #define SWAIT_HEAD_INITIALIZER(name) {                          \
26                 .lock   = __RAW_SPIN_LOCK_UNLOCKED(name.lock),  \
27                 .list   = LIST_HEAD_INIT((name).list),          \
28         }
29
30 #define DEFINE_SWAIT_HEAD(name)                                 \
31         struct swait_head name = SWAIT_HEAD_INITIALIZER(name)
32
33 extern void __init_swait_head(struct swait_head *h, struct lock_class_key *key);
34
35 #define init_swait_head(swh)                                    \
36         do {                                                    \
37                 static struct lock_class_key __key;             \
38                                                                 \
39                 __init_swait_head((swh), &__key);               \
40         } while (0)
41
42 /*
43  * Waiter functions
44  */
45 extern void swait_prepare_locked(struct swait_head *head, struct swaiter *w);
46 extern void swait_prepare(struct swait_head *head, struct swaiter *w, int state);
47 extern void swait_finish_locked(struct swait_head *head, struct swaiter *w);
48 extern void swait_finish(struct swait_head *head, struct swaiter *w);
49
50 /*
51  * Wakeup functions
52  */
53 extern unsigned int __swait_wake(struct swait_head *head, unsigned int state, unsigned int num);
54 extern unsigned int __swait_wake_locked(struct swait_head *head, unsigned int state, unsigned int num);
55
56 #define swait_wake(head)                        __swait_wake(head, TASK_NORMAL, 1)
57 #define swait_wake_interruptible(head)          __swait_wake(head, TASK_INTERRUPTIBLE, 1)
58 #define swait_wake_all(head)                    __swait_wake(head, TASK_NORMAL, 0)
59 #define swait_wake_all_interruptible(head)      __swait_wake(head, TASK_INTERRUPTIBLE, 0)
60
61 /*
62  * Event API
63  */
64 #define __swait_event(wq, condition)                                    \
65 do {                                                                    \
66         DEFINE_SWAITER(__wait);                                         \
67                                                                         \
68         for (;;) {                                                      \
69                 swait_prepare(&wq, &__wait, TASK_UNINTERRUPTIBLE);      \
70                 if (condition)                                          \
71                         break;                                          \
72                 schedule();                                             \
73         }                                                               \
74         swait_finish(&wq, &__wait);                                     \
75 } while (0)
76
77 /**
78  * swait_event - sleep until a condition gets true
79  * @wq: the waitqueue to wait on
80  * @condition: a C expression for the event to wait for
81  *
82  * The process is put to sleep (TASK_UNINTERRUPTIBLE) until the
83  * @condition evaluates to true. The @condition is checked each time
84  * the waitqueue @wq is woken up.
85  *
86  * wake_up() has to be called after changing any variable that could
87  * change the result of the wait condition.
88  */
89 #define swait_event(wq, condition)                                      \
90 do {                                                                    \
91         if (condition)                                                  \
92                 break;                                                  \
93         __swait_event(wq, condition);                                   \
94 } while (0)
95
96 #define __swait_event_interruptible(wq, condition, ret)                 \
97 do {                                                                    \
98         DEFINE_SWAITER(__wait);                                         \
99                                                                         \
100         for (;;) {                                                      \
101                 swait_prepare(&wq, &__wait, TASK_INTERRUPTIBLE);        \
102                 if (condition)                                          \
103                         break;                                          \
104                 if (signal_pending(current)) {                          \
105                         ret = -ERESTARTSYS;                             \
106                         break;                                          \
107                 }                                                       \
108                 schedule();                                             \
109         }                                                               \
110         swait_finish(&wq, &__wait);                                     \
111 } while (0)
112
113 #define __swait_event_interruptible_timeout(wq, condition, ret)         \
114 do {                                                                    \
115         DEFINE_SWAITER(__wait);                                         \
116                                                                         \
117         for (;;) {                                                      \
118                 swait_prepare(&wq, &__wait, TASK_INTERRUPTIBLE);        \
119                 if (condition)                                          \
120                         break;                                          \
121                 if (signal_pending(current)) {                          \
122                         ret = -ERESTARTSYS;                             \
123                         break;                                          \
124                 }                                                       \
125                 ret = schedule_timeout(ret);                            \
126                 if (!ret)                                               \
127                         break;                                          \
128         }                                                               \
129         swait_finish(&wq, &__wait);                                     \
130 } while (0)
131
132 /**
133  * swait_event_interruptible - sleep until a condition gets true
134  * @wq: the waitqueue to wait on
135  * @condition: a C expression for the event to wait for
136  *
137  * The process is put to sleep (TASK_INTERRUPTIBLE) until the
138  * @condition evaluates to true. The @condition is checked each time
139  * the waitqueue @wq is woken up.
140  *
141  * wake_up() has to be called after changing any variable that could
142  * change the result of the wait condition.
143  */
144 #define swait_event_interruptible(wq, condition)                        \
145 ({                                                                      \
146         int __ret = 0;                                                  \
147         if (!(condition))                                               \
148                 __swait_event_interruptible(wq, condition, __ret);      \
149         __ret;                                                          \
150 })
151
152 #define swait_event_interruptible_timeout(wq, condition, timeout)       \
153 ({                                                                      \
154         int __ret = timeout;                                            \
155         if (!(condition))                                               \
156                 __swait_event_interruptible_timeout(wq, condition, __ret);      \
157         __ret;                                                          \
158 })
159
160 #define __swait_event_timeout(wq, condition, ret)                       \
161 do {                                                                    \
162         DEFINE_SWAITER(__wait);                                         \
163                                                                         \
164         for (;;) {                                                      \
165                 swait_prepare(&wq, &__wait, TASK_UNINTERRUPTIBLE);      \
166                 if (condition)                                          \
167                         break;                                          \
168                 ret = schedule_timeout(ret);                            \
169                 if (!ret)                                               \
170                         break;                                          \
171         }                                                               \
172         swait_finish(&wq, &__wait);                                     \
173 } while (0)
174
175 /**
176  * swait_event_timeout - sleep until a condition gets true or a timeout elapses
177  * @wq: the waitqueue to wait on
178  * @condition: a C expression for the event to wait for
179  * @timeout: timeout, in jiffies
180  *
181  * The process is put to sleep (TASK_UNINTERRUPTIBLE) until the
182  * @condition evaluates to true. The @condition is checked each time
183  * the waitqueue @wq is woken up.
184  *
185  * wake_up() has to be called after changing any variable that could
186  * change the result of the wait condition.
187  *
188  * The function returns 0 if the @timeout elapsed, and the remaining
189  * jiffies if the condition evaluated to true before the timeout elapsed.
190  */
191 #define swait_event_timeout(wq, condition, timeout)                     \
192 ({                                                                      \
193         long __ret = timeout;                                           \
194         if (!(condition))                                               \
195                 __swait_event_timeout(wq, condition, __ret);            \
196         __ret;                                                          \
197 })
198
199 #endif