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