vserver 1.9.3
[linux-2.6.git] / include / linux / wait.h
1 #ifndef _LINUX_WAIT_H
2 #define _LINUX_WAIT_H
3
4 #define WNOHANG         0x00000001
5 #define WUNTRACED       0x00000002
6 #define WSTOPPED        WUNTRACED
7 #define WEXITED         0x00000004
8 #define WCONTINUED      0x00000008
9 #define WNOWAIT         0x01000000      /* Don't reap, just poll status.  */
10
11 #define __WNOTHREAD     0x20000000      /* Don't wait on children of other threads in this group */
12 #define __WALL          0x40000000      /* Wait on all children, regardless of type */
13 #define __WCLONE        0x80000000      /* Wait only on non-SIGCHLD children */
14
15 /* First argument to waitid: */
16 #define P_ALL           0
17 #define P_PID           1
18 #define P_PGID          2
19
20 #ifdef __KERNEL__
21
22 #include <linux/config.h>
23 #include <linux/list.h>
24 #include <linux/stddef.h>
25 #include <linux/spinlock.h>
26 #include <asm/system.h>
27
28 typedef struct __wait_queue wait_queue_t;
29 typedef int (*wait_queue_func_t)(wait_queue_t *wait, unsigned mode, int sync, void *key);
30 int default_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key);
31
32 struct __wait_queue {
33         unsigned int flags;
34 #define WQ_FLAG_EXCLUSIVE       0x01
35         struct task_struct * task;
36         wait_queue_func_t func;
37         struct list_head task_list;
38 };
39
40 struct __wait_queue_head {
41         spinlock_t lock;
42         struct list_head task_list;
43 };
44 typedef struct __wait_queue_head wait_queue_head_t;
45
46
47 /*
48  * Macros for declaration and initialisaton of the datatypes
49  */
50
51 #define __WAITQUEUE_INITIALIZER(name, tsk) {                            \
52         .task           = tsk,                                          \
53         .func           = default_wake_function,                        \
54         .task_list      = { NULL, NULL } }
55
56 #define DECLARE_WAITQUEUE(name, tsk)                                    \
57         wait_queue_t name = __WAITQUEUE_INITIALIZER(name, tsk)
58
59 #define __WAIT_QUEUE_HEAD_INITIALIZER(name) {                           \
60         .lock           = SPIN_LOCK_UNLOCKED,                           \
61         .task_list      = { &(name).task_list, &(name).task_list } }
62
63 #define DECLARE_WAIT_QUEUE_HEAD(name) \
64         wait_queue_head_t name = __WAIT_QUEUE_HEAD_INITIALIZER(name)
65
66 static inline void init_waitqueue_head(wait_queue_head_t *q)
67 {
68         q->lock = SPIN_LOCK_UNLOCKED;
69         INIT_LIST_HEAD(&q->task_list);
70 }
71
72 static inline void init_waitqueue_entry(wait_queue_t *q, struct task_struct *p)
73 {
74         q->flags = 0;
75         q->task = p;
76         q->func = default_wake_function;
77 }
78
79 static inline void init_waitqueue_func_entry(wait_queue_t *q,
80                                         wait_queue_func_t func)
81 {
82         q->flags = 0;
83         q->task = NULL;
84         q->func = func;
85 }
86
87 static inline int waitqueue_active(wait_queue_head_t *q)
88 {
89         return !list_empty(&q->task_list);
90 }
91
92 /*
93  * Used to distinguish between sync and async io wait context:
94  * sync i/o typically specifies a NULL wait queue entry or a wait
95  * queue entry bound to a task (current task) to wake up.
96  * aio specifies a wait queue entry with an async notification
97  * callback routine, not associated with any task.
98  */
99 #define is_sync_wait(wait)      (!(wait) || ((wait)->task))
100
101 extern void FASTCALL(add_wait_queue(wait_queue_head_t *q, wait_queue_t * wait));
102 extern void FASTCALL(add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t * wait));
103 extern void FASTCALL(remove_wait_queue(wait_queue_head_t *q, wait_queue_t * wait));
104
105 static inline void __add_wait_queue(wait_queue_head_t *head, wait_queue_t *new)
106 {
107         list_add(&new->task_list, &head->task_list);
108 }
109
110 /*
111  * Used for wake-one threads:
112  */
113 static inline void __add_wait_queue_tail(wait_queue_head_t *head,
114                                                 wait_queue_t *new)
115 {
116         list_add_tail(&new->task_list, &head->task_list);
117 }
118
119 static inline void __remove_wait_queue(wait_queue_head_t *head,
120                                                         wait_queue_t *old)
121 {
122         list_del(&old->task_list);
123 }
124
125 void FASTCALL(__wake_up(wait_queue_head_t *q, unsigned int mode, int nr, void *key));
126 extern void FASTCALL(__wake_up_locked(wait_queue_head_t *q, unsigned int mode));
127 extern void FASTCALL(__wake_up_sync(wait_queue_head_t *q, unsigned int mode, int nr));
128
129 #define wake_up(x)                      __wake_up(x, TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, 1, NULL)
130 #define wake_up_nr(x, nr)               __wake_up(x, TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, nr, NULL)
131 #define wake_up_all(x)                  __wake_up(x, TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, 0, NULL)
132 #define wake_up_all_sync(x)                     __wake_up_sync((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, 0)
133 #define wake_up_interruptible(x)        __wake_up(x, TASK_INTERRUPTIBLE, 1, NULL)
134 #define wake_up_interruptible_nr(x, nr) __wake_up(x, TASK_INTERRUPTIBLE, nr, NULL)
135 #define wake_up_interruptible_all(x)    __wake_up(x, TASK_INTERRUPTIBLE, 0, NULL)
136 #define wake_up_locked(x)               __wake_up_locked((x), TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE)
137 #define wake_up_interruptible_sync(x)   __wake_up_sync((x),TASK_INTERRUPTIBLE, 1)
138
139 #define __wait_event(wq, condition)                                     \
140 do {                                                                    \
141         DEFINE_WAIT(__wait);                                            \
142                                                                         \
143         for (;;) {                                                      \
144                 prepare_to_wait(&wq, &__wait, TASK_UNINTERRUPTIBLE);    \
145                 if (condition)                                          \
146                         break;                                          \
147                 schedule();                                             \
148         }                                                               \
149         finish_wait(&wq, &__wait);                                      \
150 } while (0)
151
152 #define wait_event(wq, condition)                                       \
153 do {                                                                    \
154         if (condition)                                                  \
155                 break;                                                  \
156         __wait_event(wq, condition);                                    \
157 } while (0)
158
159 #define __wait_event_timeout(wq, condition, ret)                        \
160 do {                                                                    \
161         DEFINE_WAIT(__wait);                                            \
162                                                                         \
163         for (;;) {                                                      \
164                 prepare_to_wait(&wq, &__wait, TASK_UNINTERRUPTIBLE);    \
165                 if (condition)                                          \
166                         break;                                          \
167                 ret = schedule_timeout(ret);                            \
168                 if (!ret)                                               \
169                         break;                                          \
170         }                                                               \
171         finish_wait(&wq, &__wait);                                      \
172 } while (0)
173
174 #define wait_event_timeout(wq, condition, timeout)                      \
175 ({                                                                      \
176         long __ret = timeout;                                           \
177         if (!(condition))                                               \
178                 __wait_event_timeout(wq, condition, __ret);             \
179         __ret;                                                          \
180 })
181
182 #define __wait_event_interruptible(wq, condition, ret)                  \
183 do {                                                                    \
184         DEFINE_WAIT(__wait);                                            \
185                                                                         \
186         for (;;) {                                                      \
187                 prepare_to_wait(&wq, &__wait, TASK_INTERRUPTIBLE);      \
188                 if (condition)                                          \
189                         break;                                          \
190                 if (!signal_pending(current)) {                         \
191                         schedule();                                     \
192                         continue;                                       \
193                 }                                                       \
194                 ret = -ERESTARTSYS;                                     \
195                 break;                                                  \
196         }                                                               \
197         finish_wait(&wq, &__wait);                                      \
198 } while (0)
199
200 #define wait_event_interruptible(wq, condition)                         \
201 ({                                                                      \
202         int __ret = 0;                                                  \
203         if (!(condition))                                               \
204                 __wait_event_interruptible(wq, condition, __ret);       \
205         __ret;                                                          \
206 })
207
208 #define __wait_event_interruptible_timeout(wq, condition, ret)          \
209 do {                                                                    \
210         DEFINE_WAIT(__wait);                                            \
211                                                                         \
212         for (;;) {                                                      \
213                 prepare_to_wait(&wq, &__wait, TASK_INTERRUPTIBLE);      \
214                 if (condition)                                          \
215                         break;                                          \
216                 if (!signal_pending(current)) {                         \
217                         ret = schedule_timeout(ret);                    \
218                         if (!ret)                                       \
219                                 break;                                  \
220                         continue;                                       \
221                 }                                                       \
222                 ret = -ERESTARTSYS;                                     \
223                 break;                                                  \
224         }                                                               \
225         finish_wait(&wq, &__wait);                                      \
226 } while (0)
227
228 #define wait_event_interruptible_timeout(wq, condition, timeout)        \
229 ({                                                                      \
230         long __ret = timeout;                                           \
231         if (!(condition))                                               \
232                 __wait_event_interruptible_timeout(wq, condition, __ret); \
233         __ret;                                                          \
234 })
235
236 #define __wait_event_interruptible_exclusive(wq, condition, ret)        \
237 do {                                                                    \
238         DEFINE_WAIT(__wait);                                            \
239                                                                         \
240         for (;;) {                                                      \
241                 prepare_to_wait_exclusive(&wq, &__wait,                 \
242                                         TASK_INTERRUPTIBLE);            \
243                 if (condition)                                          \
244                         break;                                          \
245                 if (!signal_pending(current)) {                         \
246                         schedule();                                     \
247                         continue;                                       \
248                 }                                                       \
249                 ret = -ERESTARTSYS;                                     \
250                 break;                                                  \
251         }                                                               \
252         finish_wait(&wq, &__wait);                                      \
253 } while (0)
254
255 #define wait_event_interruptible_exclusive(wq, condition)               \
256 ({                                                                      \
257         int __ret = 0;                                                  \
258         if (!(condition))                                               \
259                 __wait_event_interruptible_exclusive(wq, condition, __ret);\
260         __ret;                                                          \
261 })
262
263 /*
264  * Must be called with the spinlock in the wait_queue_head_t held.
265  */
266 static inline void add_wait_queue_exclusive_locked(wait_queue_head_t *q,
267                                                    wait_queue_t * wait)
268 {
269         wait->flags |= WQ_FLAG_EXCLUSIVE;
270         __add_wait_queue_tail(q,  wait);
271 }
272
273 /*
274  * Must be called with the spinlock in the wait_queue_head_t held.
275  */
276 static inline void remove_wait_queue_locked(wait_queue_head_t *q,
277                                             wait_queue_t * wait)
278 {
279         __remove_wait_queue(q,  wait);
280 }
281
282 /*
283  * These are the old interfaces to sleep waiting for an event.
284  * They are racy.  DO NOT use them, use the wait_event* interfaces above.  
285  * We plan to remove these interfaces during 2.7.
286  */
287 extern void FASTCALL(sleep_on(wait_queue_head_t *q));
288 extern long FASTCALL(sleep_on_timeout(wait_queue_head_t *q,
289                                       signed long timeout));
290 extern void FASTCALL(interruptible_sleep_on(wait_queue_head_t *q));
291 extern long FASTCALL(interruptible_sleep_on_timeout(wait_queue_head_t *q,
292                                                     signed long timeout));
293
294 /*
295  * Waitqueues which are removed from the waitqueue_head at wakeup time
296  */
297 void FASTCALL(prepare_to_wait(wait_queue_head_t *q,
298                                 wait_queue_t *wait, int state));
299 void FASTCALL(prepare_to_wait_exclusive(wait_queue_head_t *q,
300                                 wait_queue_t *wait, int state));
301 void FASTCALL(finish_wait(wait_queue_head_t *q, wait_queue_t *wait));
302 int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key);
303
304 #define DEFINE_WAIT(name)                                               \
305         wait_queue_t name = {                                           \
306                 .task           = current,                              \
307                 .func           = autoremove_wake_function,             \
308                 .task_list      = {     .next = &name.task_list,        \
309                                         .prev = &name.task_list,        \
310                                 },                                      \
311         }
312
313 #define init_wait(wait)                                                 \
314         do {                                                            \
315                 wait->task = current;                                   \
316                 wait->func = autoremove_wake_function;                  \
317                 INIT_LIST_HEAD(&wait->task_list);                       \
318         } while (0)
319         
320 #endif /* __KERNEL__ */
321
322 #endif