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 |