Subversion Repositories shark

Rev

Rev 422 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
422 giacomo 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);
21
extern int default_wake_function(wait_queue_t *wait, unsigned mode, int sync);
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
 
490 giacomo 57
extern void init_waitqueue_head(wait_queue_head_t *q);
422 giacomo 58
 
490 giacomo 59
extern void init_waitqueue_entry(wait_queue_t *q, struct task_struct *p);
422 giacomo 60
 
490 giacomo 61
extern void init_waitqueue_func_entry(wait_queue_t *q,
62
                                        wait_queue_func_t func);
422 giacomo 63
 
490 giacomo 64
extern int waitqueue_active(wait_queue_head_t *q);
422 giacomo 65
 
66
extern void FASTCALL(add_wait_queue(wait_queue_head_t *q, wait_queue_t * wait));
67
extern void FASTCALL(add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t * wait));
68
extern void FASTCALL(remove_wait_queue(wait_queue_head_t *q, wait_queue_t * wait));
69
 
490 giacomo 70
extern void __add_wait_queue(wait_queue_head_t *head, wait_queue_t *new);
422 giacomo 71
 
72
/*
73
 * Used for wake-one threads:
74
 */
75
static inline void __add_wait_queue_tail(wait_queue_head_t *head,
76
                                                wait_queue_t *new)
77
{
78
        list_add_tail(&new->task_list, &head->task_list);
79
}
80
 
81
static inline void __remove_wait_queue(wait_queue_head_t *head,
82
                                                        wait_queue_t *old)
83
{
84
        list_del(&old->task_list);
85
}
86
 
87
extern void FASTCALL(__wake_up(wait_queue_head_t *q, unsigned int mode, int nr));
88
extern void FASTCALL(__wake_up_locked(wait_queue_head_t *q, unsigned int mode));
89
extern void FASTCALL(__wake_up_sync(wait_queue_head_t *q, unsigned int mode, int nr));
90
 
91
#define wake_up(x)                      __wake_up((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, 1)
92
#define wake_up_nr(x, nr)               __wake_up((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, nr)
93
#define wake_up_all(x)                  __wake_up((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, 0)
94
#define wake_up_all_sync(x)                     __wake_up_sync((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, 0)
95
#define wake_up_interruptible(x)        __wake_up((x),TASK_INTERRUPTIBLE, 1)
96
#define wake_up_interruptible_nr(x, nr) __wake_up((x),TASK_INTERRUPTIBLE, nr)
97
#define wake_up_interruptible_all(x)    __wake_up((x),TASK_INTERRUPTIBLE, 0)
98
#define wake_up_locked(x)               __wake_up_locked((x), TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE)
99
#define wake_up_interruptible_sync(x)   __wake_up_sync((x),TASK_INTERRUPTIBLE, 1)
100
 
101
#define __wait_event(wq, condition)                                     \
102
do {                                                                    \
103
        wait_queue_t __wait;                                            \
104
        init_waitqueue_entry(&__wait, current);                         \
105
                                                                        \
106
        add_wait_queue(&wq, &__wait);                                   \
107
        for (;;) {                                                      \
108
                set_current_state(TASK_UNINTERRUPTIBLE);                \
109
                if (condition)                                          \
110
                        break;                                          \
111
                schedule();                                             \
112
        }                                                               \
113
        current->state = TASK_RUNNING;                                  \
114
        remove_wait_queue(&wq, &__wait);                                \
115
} while (0)
116
 
117
#define wait_event(wq, condition)                                       \
118
do {                                                                    \
119
        if (condition)                                                  \
120
                break;                                                  \
121
        __wait_event(wq, condition);                                    \
122
} while (0)
123
 
124
#define __wait_event_interruptible(wq, condition, ret)                  \
125
do {                                                                    \
126
        wait_queue_t __wait;                                            \
127
        init_waitqueue_entry(&__wait, current);                         \
128
                                                                        \
129
        add_wait_queue(&wq, &__wait);                                   \
130
        for (;;) {                                                      \
131
                set_current_state(TASK_INTERRUPTIBLE);                  \
132
                if (condition)                                          \
133
                        break;                                          \
134
                if (!signal_pending(current)) {                         \
135
                        schedule();                                     \
136
                        continue;                                       \
137
                }                                                       \
138
                ret = -ERESTARTSYS;                                     \
139
                break;                                                  \
140
        }                                                               \
141
        current->state = TASK_RUNNING;                                  \
142
        remove_wait_queue(&wq, &__wait);                                \
143
} while (0)
144
 
145
#define wait_event_interruptible(wq, condition)                         \
146
({                                                                      \
147
        int __ret = 0;                                                  \
148
        if (!(condition))                                               \
149
                __wait_event_interruptible(wq, condition, __ret);       \
150
        __ret;                                                          \
151
})
152
 
153
#define __wait_event_interruptible_timeout(wq, condition, ret)          \
154
do {                                                                    \
155
        wait_queue_t __wait;                                            \
156
        init_waitqueue_entry(&__wait, current);                         \
157
                                                                        \
158
        add_wait_queue(&wq, &__wait);                                   \
159
        for (;;) {                                                      \
160
                set_current_state(TASK_INTERRUPTIBLE);                  \
161
                if (condition)                                          \
162
                        break;                                          \
163
                if (!signal_pending(current)) {                         \
164
                        ret = schedule_timeout(ret);                    \
165
                        if (!ret)                                       \
166
                                break;                                  \
167
                        continue;                                       \
168
                }                                                       \
169
                ret = -ERESTARTSYS;                                     \
170
                break;                                                  \
171
        }                                                               \
172
        current->state = TASK_RUNNING;                                  \
173
        remove_wait_queue(&wq, &__wait);                                \
174
} while (0)
175
 
176
#define wait_event_interruptible_timeout(wq, condition, timeout)        \
177
({                                                                      \
178
        long __ret = timeout;                                           \
179
        if (!(condition))                                               \
180
                __wait_event_interruptible_timeout(wq, condition, __ret); \
181
        __ret;                                                          \
182
})
183
 
184
/*
185
 * Must be called with the spinlock in the wait_queue_head_t held.
186
 */
187
static inline void add_wait_queue_exclusive_locked(wait_queue_head_t *q,
188
                                                   wait_queue_t * wait)
189
{
190
        wait->flags |= WQ_FLAG_EXCLUSIVE;
191
        __add_wait_queue_tail(q,  wait);
192
}
193
 
194
/*
195
 * Must be called with the spinlock in the wait_queue_head_t held.
196
 */
197
static inline void remove_wait_queue_locked(wait_queue_head_t *q,
198
                                            wait_queue_t * wait)
199
{
200
        __remove_wait_queue(q,  wait);
201
}
202
 
203
/*
204
 * These are the old interfaces to sleep waiting for an event.
205
 * They are racy.  DO NOT use them, use the wait_event* interfaces above.  
206
 * We plan to remove these interfaces during 2.7.
207
 */
208
extern void FASTCALL(sleep_on(wait_queue_head_t *q));
209
extern long FASTCALL(sleep_on_timeout(wait_queue_head_t *q,
210
                                      signed long timeout));
211
extern void FASTCALL(interruptible_sleep_on(wait_queue_head_t *q));
212
extern long FASTCALL(interruptible_sleep_on_timeout(wait_queue_head_t *q,
213
                                                    signed long timeout));
214
 
215
/*
216
 * Waitqueues which are removed from the waitqueue_head at wakeup time
217
 */
218
void FASTCALL(prepare_to_wait(wait_queue_head_t *q,
219
                                wait_queue_t *wait, int state));
220
void FASTCALL(prepare_to_wait_exclusive(wait_queue_head_t *q,
221
                                wait_queue_t *wait, int state));
222
void FASTCALL(finish_wait(wait_queue_head_t *q, wait_queue_t *wait));
223
int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync);
224
 
225
#define DEFINE_WAIT(name)                                               \
226
        wait_queue_t name = {                                           \
227
                .task           = current,                              \
228
                .func           = autoremove_wake_function,             \
229
                .task_list      = {     .next = &name.task_list,        \
230
                                        .prev = &name.task_list,        \
231
                                },                                      \
232
        }
233
 
234
#define init_wait(wait)                                                 \
235
        do {                                                            \
236
                wait->task = current;                                   \
237
                wait->func = autoremove_wake_function;                  \
238
                INIT_LIST_HEAD(&wait->task_list);                       \
239
        } while (0)
240
 
241
#endif /* __KERNEL__ */
242
 
243
#endif