Subversion Repositories Kolibri OS

Rev

Rev 5056 | Rev 6102 | 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 
2967 Serge 10
 
4292 Serge 11
 
5270 serge 12
 
3192 Serge 13
#include 
14
 
2967 Serge 15
typedef struct __wait_queue wait_queue_t;
3391 Serge 16
typedef int (*wait_queue_func_t)(wait_queue_t *wait, unsigned mode, int flags, void *key);
4292 Serge 17
int default_wake_function(wait_queue_t *wait, unsigned mode, int flags, void *key);
3391 Serge 18
 
2967 Serge 19
typedef struct __wait_queue_head wait_queue_head_t;
20
 
21
struct __wait_queue
22
{
3391 Serge 23
    wait_queue_func_t func;
2967 Serge 24
    struct list_head task_list;
25
    evhandle_t evnt;
26
};
27
 
28
struct __wait_queue_head
29
{
30
    spinlock_t lock;
31
    struct list_head task_list;
32
};
4292 Serge 33
static inline int waitqueue_active(wait_queue_head_t *q)
34
{
35
	return !list_empty(&q->task_list);
36
}
2967 Serge 37
 
5270 serge 38
extern void add_wait_queue(wait_queue_head_t *q, wait_queue_t *wait);
39
extern void add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t *wait);
40
extern void remove_wait_queue(wait_queue_head_t *q, wait_queue_t *wait);
41
 
2967 Serge 42
static inline void __add_wait_queue(wait_queue_head_t *head, wait_queue_t *new)
43
{
44
    list_add(&new->task_list, &head->task_list);
45
}
46
 
3482 Serge 47
/*
2967 Serge 48
#define __wait_event(wq, condition)                                     \
49
do {                                                                    \
50
        DEFINE_WAIT(__wait);                                            \
51
                                                                        \
52
        for (;;) {                                                      \
53
                prepare_to_wait(&wq, &__wait, TASK_UNINTERRUPTIBLE);    \
54
                if (condition)                                          \
55
                        break;                                          \
56
                schedule();                                             \
57
        }                                                               \
58
        finish_wait(&wq, &__wait);                                      \
59
} while (0)
60
 
3482 Serge 61
*/
2967 Serge 62
 
3031 serge 63
#define wait_event_timeout(wq, condition, timeout)          \
64
({                                                          \
65
    long __ret = timeout;                                   \
66
do{                                                         \
67
    wait_queue_t __wait = {                                 \
68
        .task_list = LIST_HEAD_INIT(__wait.task_list),      \
69
        .evnt      = CreateEvent(NULL, MANUAL_DESTROY),     \
70
    };                                                      \
3297 Serge 71
    unsigned long flags;                                    \
3031 serge 72
                                                            \
73
    spin_lock_irqsave(&wq.lock, flags);                     \
74
    if (list_empty(&__wait.task_list))                      \
75
        __add_wait_queue(&wq, &__wait);                     \
76
    spin_unlock_irqrestore(&wq.lock, flags);                \
77
                                                            \
78
    for(;;){                                                \
79
        if (condition)                                      \
80
            break;                                          \
3391 Serge 81
        WaitEventTimeout(__wait.evnt, timeout);             \
3031 serge 82
    };                                                      \
3297 Serge 83
    if (!list_empty(&__wait.task_list)) {                   \
3031 serge 84
        spin_lock_irqsave(&wq.lock, flags);                 \
85
        list_del_init(&__wait.task_list);                   \
86
        spin_unlock_irqrestore(&wq.lock, flags);            \
87
    };                                                      \
88
    DestroyEvent(__wait.evnt);                              \
89
} while (0);                                                \
90
    __ret;                                                  \
91
})
92
 
3192 Serge 93
#define wait_event_interruptible_timeout(wq, condition, timeout)    \
94
        wait_event_timeout(wq, condition, timeout)
3031 serge 95
 
96
 
2967 Serge 97
#define wait_event(wq, condition)                           \
5056 serge 98
    do{                                                     \
2967 Serge 99
    wait_queue_t __wait = {                                 \
100
        .task_list = LIST_HEAD_INIT(__wait.task_list),      \
101
        .evnt      = CreateEvent(NULL, MANUAL_DESTROY),     \
102
    };                                                      \
3297 Serge 103
    unsigned long flags;                                    \
2967 Serge 104
                                                            \
105
    spin_lock_irqsave(&wq.lock, flags);                     \
106
    if (list_empty(&__wait.task_list))                      \
107
        __add_wait_queue(&wq, &__wait);                     \
108
    spin_unlock_irqrestore(&wq.lock, flags);                \
109
                                                            \
110
    for(;;){                                                \
111
        if (condition)                                      \
112
            break;                                          \
113
        WaitEvent(__wait.evnt);                             \
114
    };                                                      \
115
    if (!list_empty_careful(&__wait.task_list)) {           \
116
        spin_lock_irqsave(&wq.lock, flags);                 \
117
        list_del_init(&__wait.task_list);                   \
118
        spin_unlock_irqrestore(&wq.lock, flags);            \
119
    };                                                      \
120
    DestroyEvent(__wait.evnt);                              \
121
} while (0)
122
 
5056 serge 123
#define wait_event_interruptible(wq, condition)             \
124
({                                                          \
125
    int __ret = 0;                                          \
126
    if (!(condition))                                       \
127
        wait_event(wq, condition);                          \
128
    __ret;                                                  \
129
})
2967 Serge 130
 
3031 serge 131
 
2967 Serge 132
static inline
133
void wake_up_all(wait_queue_head_t *q)
134
{
135
    wait_queue_t *curr;
136
    unsigned long flags;
137
 
138
    spin_lock_irqsave(&q->lock, flags);
139
    list_for_each_entry(curr, &q->task_list, task_list)
140
    {
3297 Serge 141
//        printf("raise event \n");
142
 
2967 Serge 143
        kevent_t event;
144
        event.code = -1;
145
        RaiseEvent(curr->evnt, 0, &event);
146
    }
147
    spin_unlock_irqrestore(&q->lock, flags);
148
}
149
 
150
 
151
static inline void
152
init_waitqueue_head(wait_queue_head_t *q)
153
{
154
    spin_lock_init(&q->lock);
155
    INIT_LIST_HEAD(&q->task_list);
156
};
157
 
158
 
5270 serge 159
//struct completion {
160
//    unsigned int done;
161
//    wait_queue_head_t wait;
162
//};
3031 serge 163
 
3391 Serge 164
int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key);
3031 serge 165
 
3391 Serge 166
 
167
#define DEFINE_WAIT_FUNC(name, function)                                \
168
        wait_queue_t name = {                                           \
169
                .func           = function,                             \
170
                .task_list      = LIST_HEAD_INIT((name).task_list),     \
171
                .evnt           = CreateEvent(NULL, MANUAL_DESTROY),    \
172
        }
173
 
174
#define DEFINE_WAIT(name) DEFINE_WAIT_FUNC(name, autoremove_wake_function)
175
 
176
 
2967 Serge 177
#endif
178