patch-2_6_7-vs1_9_1_12
[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         wait_queue_t __wait;                                            \
124         init_waitqueue_entry(&__wait, current);                         \
125                                                                         \
126         add_wait_queue(&wq, &__wait);                                   \
127         for (;;) {                                                      \
128                 set_current_state(TASK_UNINTERRUPTIBLE);                \
129                 if (condition)                                          \
130                         break;                                          \
131                 schedule();                                             \
132         }                                                               \
133         current->state = TASK_RUNNING;                                  \
134         remove_wait_queue(&wq, &__wait);                                \
135 } while (0)
136
137 #define wait_event(wq, condition)                                       \
138 do {                                                                    \
139         if (condition)                                                  \
140                 break;                                                  \
141         __wait_event(wq, condition);                                    \
142 } while (0)
143
144 #define __wait_event_interruptible(wq, condition, ret)                  \
145 do {                                                                    \
146         wait_queue_t __wait;                                            \
147         init_waitqueue_entry(&__wait, current);                         \
148                                                                         \
149         add_wait_queue(&wq, &__wait);                                   \
150         for (;;) {                                                      \
151                 set_current_state(TASK_INTERRUPTIBLE);                  \
152                 if (condition)                                          \
153                         break;                                          \
154                 if (!signal_pending(current)) {                         \
155                         schedule();                                     \
156                         continue;                                       \
157                 }                                                       \
158                 ret = -ERESTARTSYS;                                     \
159                 break;                                                  \
160         }                                                               \
161         current->state = TASK_RUNNING;                                  \
162         remove_wait_queue(&wq, &__wait);                                \
163 } while (0)
164
165 #define wait_event_interruptible(wq, condition)                         \
166 ({                                                                      \
167         int __ret = 0;                                                  \
168         if (!(condition))                                               \
169                 __wait_event_interruptible(wq, condition, __ret);       \
170         __ret;                                                          \
171 })
172
173 #define __wait_event_interruptible_timeout(wq, condition, ret)          \
174 do {                                                                    \
175         wait_queue_t __wait;                                            \
176         init_waitqueue_entry(&__wait, current);                         \
177                                                                         \
178         add_wait_queue(&wq, &__wait);                                   \
179         for (;;) {                                                      \
180                 set_current_state(TASK_INTERRUPTIBLE);                  \
181                 if (condition)                                          \
182                         break;                                          \
183                 if (!signal_pending(current)) {                         \
184                         ret = schedule_timeout(ret);                    \
185                         if (!ret)                                       \
186                                 break;                                  \
187                         continue;                                       \
188                 }                                                       \
189                 ret = -ERESTARTSYS;                                     \
190                 break;                                                  \
191         }                                                               \
192         current->state = TASK_RUNNING;                                  \
193         remove_wait_queue(&wq, &__wait);                                \
194 } while (0)
195
196 #define wait_event_interruptible_timeout(wq, condition, timeout)        \
197 ({                                                                      \
198         long __ret = timeout;                                           \
199         if (!(condition))                                               \
200                 __wait_event_interruptible_timeout(wq, condition, __ret); \
201         __ret;                                                          \
202 })
203         
204 /*
205  * Must be called with the spinlock in the wait_queue_head_t held.
206  */
207 static inline void add_wait_queue_exclusive_locked(wait_queue_head_t *q,
208                                                    wait_queue_t * wait)
209 {
210         wait->flags |= WQ_FLAG_EXCLUSIVE;
211         __add_wait_queue_tail(q,  wait);
212 }
213
214 /*
215  * Must be called with the spinlock in the wait_queue_head_t held.
216  */
217 static inline void remove_wait_queue_locked(wait_queue_head_t *q,
218                                             wait_queue_t * wait)
219 {
220         __remove_wait_queue(q,  wait);
221 }
222
223 /*
224  * These are the old interfaces to sleep waiting for an event.
225  * They are racy.  DO NOT use them, use the wait_event* interfaces above.  
226  * We plan to remove these interfaces during 2.7.
227  */
228 extern void FASTCALL(sleep_on(wait_queue_head_t *q));
229 extern long FASTCALL(sleep_on_timeout(wait_queue_head_t *q,
230                                       signed long timeout));
231 extern void FASTCALL(interruptible_sleep_on(wait_queue_head_t *q));
232 extern long FASTCALL(interruptible_sleep_on_timeout(wait_queue_head_t *q,
233                                                     signed long timeout));
234
235 /*
236  * Waitqueues which are removed from the waitqueue_head at wakeup time
237  */
238 void FASTCALL(prepare_to_wait(wait_queue_head_t *q,
239                                 wait_queue_t *wait, int state));
240 void FASTCALL(prepare_to_wait_exclusive(wait_queue_head_t *q,
241                                 wait_queue_t *wait, int state));
242 void FASTCALL(finish_wait(wait_queue_head_t *q, wait_queue_t *wait));
243 int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key);
244
245 #define DEFINE_WAIT(name)                                               \
246         wait_queue_t name = {                                           \
247                 .task           = current,                              \
248                 .func           = autoremove_wake_function,             \
249                 .task_list      = {     .next = &name.task_list,        \
250                                         .prev = &name.task_list,        \
251                                 },                                      \
252         }
253
254 #define init_wait(wait)                                                 \
255         do {                                                            \
256                 wait->task = current;                                   \
257                 wait->func = autoremove_wake_function;                  \
258                 INIT_LIST_HEAD(&wait->task_list);                       \
259         } while (0)
260         
261 #endif /* __KERNEL__ */
262
263 #endif