Subversion Repositories shark

Rev

Rev 847 | Details | Compare with Previous | Last modification | View Log | RSS feed

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