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