Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
2967 Serge 1
#ifndef _LINUX_WAIT_H
2
#define _LINUX_WAIT_H
5270 serge 3
/*
4
 * Linux wait queue related types and methods
5
 */
6
#include 
7
#include 
8
#include 
9
#include 
3192 Serge 10
#include 
11
 
2967 Serge 12
typedef struct __wait_queue wait_queue_t;
3391 Serge 13
typedef int (*wait_queue_func_t)(wait_queue_t *wait, unsigned mode, int flags, void *key);
4292 Serge 14
int default_wake_function(wait_queue_t *wait, unsigned mode, int flags, void *key);
3391 Serge 15
 
6102 serge 16
/* __wait_queue::flags */
17
#define WQ_FLAG_EXCLUSIVE	0x01
18
#define WQ_FLAG_WOKEN		0x02
19
 
20
struct __wait_queue {
21
	unsigned int		flags;
22
	void			*private;
23
	wait_queue_func_t	func;
24
	struct list_head	task_list;
25
	evhandle_t evnt;
26
};
27
 
28
struct wait_bit_key {
29
	void			*flags;
30
	int			bit_nr;
31
#define WAIT_ATOMIC_T_BIT_NR	-1
32
	unsigned long		timeout;
33
};
34
 
35
struct wait_bit_queue {
36
	struct wait_bit_key	key;
37
	wait_queue_t		wait;
38
};
39
 
40
struct __wait_queue_head {
41
	spinlock_t		lock;
42
	struct list_head	task_list;
43
};
2967 Serge 44
typedef struct __wait_queue_head wait_queue_head_t;
45
 
6102 serge 46
struct task_struct;
47
 
48
/*
49
 * Macros for declaration and initialisaton of the datatypes
50
 */
51
 
52
#define __WAITQUEUE_INITIALIZER(name, tsk) {				\
53
	.private	= tsk,						\
54
	.func		= default_wake_function,			\
55
	.task_list	= { NULL, NULL } }
56
 
57
#define DECLARE_WAITQUEUE(name, tsk)					\
58
	wait_queue_t name = __WAITQUEUE_INITIALIZER(name, tsk)
59
 
60
#define __WAIT_QUEUE_HEAD_INITIALIZER(name) {				\
61
	.lock		= __SPIN_LOCK_UNLOCKED(name.lock),		\
62
	.task_list	= { &(name).task_list, &(name).task_list } }
63
 
64
#define DECLARE_WAIT_QUEUE_HEAD(name) \
65
	wait_queue_head_t name = __WAIT_QUEUE_HEAD_INITIALIZER(name)
66
 
67
#define __WAIT_BIT_KEY_INITIALIZER(word, bit)				\
68
	{ .flags = word, .bit_nr = bit, }
69
 
70
#define __WAIT_ATOMIC_T_KEY_INITIALIZER(p)				\
71
	{ .flags = p, .bit_nr = WAIT_ATOMIC_T_BIT_NR, }
72
 
73
extern void __init_waitqueue_head(wait_queue_head_t *q, const char *name, struct lock_class_key *);
74
 
75
#ifdef CONFIG_LOCKDEP
76
# define __WAIT_QUEUE_HEAD_INIT_ONSTACK(name) \
77
	({ init_waitqueue_head(&name); name; })
78
# define DECLARE_WAIT_QUEUE_HEAD_ONSTACK(name) \
79
	wait_queue_head_t name = __WAIT_QUEUE_HEAD_INIT_ONSTACK(name)
80
#else
81
# define DECLARE_WAIT_QUEUE_HEAD_ONSTACK(name) DECLARE_WAIT_QUEUE_HEAD(name)
82
#endif
83
 
84
static inline void init_waitqueue_entry(wait_queue_t *q, struct task_struct *p)
2967 Serge 85
{
6102 serge 86
	q->flags	= 0;
87
	q->private	= p;
88
	q->func		= default_wake_function;
89
}
2967 Serge 90
 
6102 serge 91
static inline void
92
init_waitqueue_func_entry(wait_queue_t *q, wait_queue_func_t func)
2967 Serge 93
{
6102 serge 94
	q->flags	= 0;
95
	q->private	= NULL;
96
	q->func		= func;
97
}
98
 
4292 Serge 99
static inline int waitqueue_active(wait_queue_head_t *q)
100
{
101
	return !list_empty(&q->task_list);
102
}
2967 Serge 103
 
5270 serge 104
extern void add_wait_queue(wait_queue_head_t *q, wait_queue_t *wait);
105
extern void add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t *wait);
106
extern void remove_wait_queue(wait_queue_head_t *q, wait_queue_t *wait);
107
 
2967 Serge 108
static inline void __add_wait_queue(wait_queue_head_t *head, wait_queue_t *new)
109
{
6102 serge 110
	list_add(&new->task_list, &head->task_list);
2967 Serge 111
}
112
 
3482 Serge 113
/*
6102 serge 114
 * Used for wake-one threads:
115
 */
116
static inline void
117
__add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t *wait)
118
{
119
	wait->flags |= WQ_FLAG_EXCLUSIVE;
120
	__add_wait_queue(q, wait);
121
}
122
 
123
static inline void __add_wait_queue_tail(wait_queue_head_t *head,
124
					 wait_queue_t *new)
125
{
126
	list_add_tail(&new->task_list, &head->task_list);
127
}
128
 
129
static inline void
130
__add_wait_queue_tail_exclusive(wait_queue_head_t *q, wait_queue_t *wait)
131
{
132
	wait->flags |= WQ_FLAG_EXCLUSIVE;
133
	__add_wait_queue_tail(q, wait);
134
}
135
 
136
static inline void
137
__remove_wait_queue(wait_queue_head_t *head, wait_queue_t *old)
138
{
139
	list_del(&old->task_list);
140
}
141
 
142
typedef int wait_bit_action_f(struct wait_bit_key *, int mode);
143
void __wake_up(wait_queue_head_t *q, unsigned int mode, int nr, void *key);
144
void __wake_up_locked_key(wait_queue_head_t *q, unsigned int mode, void *key);
145
void __wake_up_sync_key(wait_queue_head_t *q, unsigned int mode, int nr, void *key);
146
void __wake_up_locked(wait_queue_head_t *q, unsigned int mode, int nr);
147
void __wake_up_sync(wait_queue_head_t *q, unsigned int mode, int nr);
148
void __wake_up_bit(wait_queue_head_t *, void *, int);
149
int __wait_on_bit(wait_queue_head_t *, struct wait_bit_queue *, wait_bit_action_f *, unsigned);
150
int __wait_on_bit_lock(wait_queue_head_t *, struct wait_bit_queue *, wait_bit_action_f *, unsigned);
151
void wake_up_bit(void *, int);
152
void wake_up_atomic_t(atomic_t *);
153
int out_of_line_wait_on_bit(void *, int, wait_bit_action_f *, unsigned);
154
int out_of_line_wait_on_bit_timeout(void *, int, wait_bit_action_f *, unsigned, unsigned long);
155
int out_of_line_wait_on_bit_lock(void *, int, wait_bit_action_f *, unsigned);
156
int out_of_line_wait_on_atomic_t(atomic_t *, int (*)(atomic_t *), unsigned);
157
wait_queue_head_t *bit_waitqueue(void *, int);
158
 
159
/*
160
 
2967 Serge 161
#define __wait_event(wq, condition)                                     \
162
do {                                                                    \
163
        DEFINE_WAIT(__wait);                                            \
164
                                                                        \
165
        for (;;) {                                                      \
166
                prepare_to_wait(&wq, &__wait, TASK_UNINTERRUPTIBLE);    \
167
                if (condition)                                          \
168
                        break;                                          \
169
                schedule();                                             \
170
        }                                                               \
171
        finish_wait(&wq, &__wait);                                      \
172
} while (0)
173
 
3482 Serge 174
*/
2967 Serge 175
 
3031 serge 176
#define wait_event_timeout(wq, condition, timeout)          \
177
({                                                          \
178
    long __ret = timeout;                                   \
179
do{                                                         \
180
    wait_queue_t __wait = {                                 \
181
        .task_list = LIST_HEAD_INIT(__wait.task_list),      \
182
        .evnt      = CreateEvent(NULL, MANUAL_DESTROY),     \
183
    };                                                      \
3297 Serge 184
    unsigned long flags;                                    \
3031 serge 185
                                                            \
186
    spin_lock_irqsave(&wq.lock, flags);                     \
187
    if (list_empty(&__wait.task_list))                      \
188
        __add_wait_queue(&wq, &__wait);                     \
189
    spin_unlock_irqrestore(&wq.lock, flags);                \
190
                                                            \
191
    for(;;){                                                \
192
        if (condition)                                      \
193
            break;                                          \
3391 Serge 194
        WaitEventTimeout(__wait.evnt, timeout);             \
3031 serge 195
    };                                                      \
3297 Serge 196
    if (!list_empty(&__wait.task_list)) {                   \
3031 serge 197
        spin_lock_irqsave(&wq.lock, flags);                 \
198
        list_del_init(&__wait.task_list);                   \
199
        spin_unlock_irqrestore(&wq.lock, flags);            \
200
    };                                                      \
201
    DestroyEvent(__wait.evnt);                              \
202
} while (0);                                                \
203
    __ret;                                                  \
204
})
205
 
3192 Serge 206
#define wait_event_interruptible_timeout(wq, condition, timeout)    \
207
        wait_event_timeout(wq, condition, timeout)
3031 serge 208
 
209
 
2967 Serge 210
#define wait_event(wq, condition)                           \
5056 serge 211
    do{                                                     \
2967 Serge 212
    wait_queue_t __wait = {                                 \
213
        .task_list = LIST_HEAD_INIT(__wait.task_list),      \
214
        .evnt      = CreateEvent(NULL, MANUAL_DESTROY),     \
215
    };                                                      \
3297 Serge 216
    unsigned long flags;                                    \
2967 Serge 217
                                                            \
218
    spin_lock_irqsave(&wq.lock, flags);                     \
219
    if (list_empty(&__wait.task_list))                      \
220
        __add_wait_queue(&wq, &__wait);                     \
221
    spin_unlock_irqrestore(&wq.lock, flags);                \
222
                                                            \
223
    for(;;){                                                \
224
        if (condition)                                      \
225
            break;                                          \
226
        WaitEvent(__wait.evnt);                             \
227
    };                                                      \
228
    if (!list_empty_careful(&__wait.task_list)) {           \
229
        spin_lock_irqsave(&wq.lock, flags);                 \
230
        list_del_init(&__wait.task_list);                   \
231
        spin_unlock_irqrestore(&wq.lock, flags);            \
232
    };                                                      \
233
    DestroyEvent(__wait.evnt);                              \
234
} while (0)
235
 
5056 serge 236
#define wait_event_interruptible(wq, condition)             \
237
({                                                          \
238
    int __ret = 0;                                          \
239
    if (!(condition))                                       \
240
        wait_event(wq, condition);                          \
241
    __ret;                                                  \
242
})
2967 Serge 243
 
6102 serge 244
static inline
245
void wake_up(wait_queue_head_t *q)
246
{
247
    wait_queue_t *curr;
248
    unsigned long flags;
3031 serge 249
 
6102 serge 250
    spin_lock_irqsave(&q->lock, flags);
251
    curr = list_first_entry(&q->task_list, typeof(*curr), task_list);
252
    {
253
//        printf("raise event \n");
254
        kevent_t event;
255
        event.code = -1;
256
        RaiseEvent(curr->evnt, 0, &event);
257
    }
258
    spin_unlock_irqrestore(&q->lock, flags);
259
}
260
 
2967 Serge 261
static inline
6102 serge 262
void wake_up_interruptible(wait_queue_head_t *q)
263
{
264
    wait_queue_t *curr;
265
    unsigned long flags;
266
 
267
    spin_lock_irqsave(&q->lock, flags);
268
    curr = list_first_entry(&q->task_list, typeof(*curr), task_list);
269
    {
270
//        printf("raise event \n");
271
        kevent_t event;
272
        event.code = -1;
273
        RaiseEvent(curr->evnt, 0, &event);
274
    }
275
    spin_unlock_irqrestore(&q->lock, flags);
276
}
277
 
278
static inline
2967 Serge 279
void wake_up_all(wait_queue_head_t *q)
280
{
281
    wait_queue_t *curr;
282
    unsigned long flags;
283
 
284
    spin_lock_irqsave(&q->lock, flags);
285
    list_for_each_entry(curr, &q->task_list, task_list)
286
    {
3297 Serge 287
//        printf("raise event \n");
2967 Serge 288
        kevent_t event;
289
        event.code = -1;
290
        RaiseEvent(curr->evnt, 0, &event);
291
    }
292
    spin_unlock_irqrestore(&q->lock, flags);
293
}
294
 
295
 
296
static inline void
297
init_waitqueue_head(wait_queue_head_t *q)
298
{
299
    spin_lock_init(&q->lock);
300
    INIT_LIST_HEAD(&q->task_list);
301
};
302
 
303
 
5270 serge 304
//struct completion {
305
//    unsigned int done;
306
//    wait_queue_head_t wait;
307
//};
3031 serge 308
 
3391 Serge 309
int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key);
3031 serge 310
 
3391 Serge 311
 
312
#define DEFINE_WAIT_FUNC(name, function)                                \
313
        wait_queue_t name = {                                           \
314
                .func           = function,                             \
315
                .task_list      = LIST_HEAD_INIT((name).task_list),     \
316
                .evnt           = CreateEvent(NULL, MANUAL_DESTROY),    \
317
        }
318
 
319
#define DEFINE_WAIT(name) DEFINE_WAIT_FUNC(name, autoremove_wake_function)
320
 
321
 
2967 Serge 322
#endif
323