Rev 552 | Rev 615 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 552 | Rev 557 | ||
---|---|---|---|
Line 31... | Line 31... | ||
31 | #include <synch/spinlock.h> |
31 | #include <synch/spinlock.h> |
32 | #include <proc/thread.h> |
32 | #include <proc/thread.h> |
33 | #include <proc/scheduler.h> |
33 | #include <proc/scheduler.h> |
34 | #include <arch/asm.h> |
34 | #include <arch/asm.h> |
35 | #include <arch/types.h> |
35 | #include <arch/types.h> |
- | 36 | #include <typedefs.h> |
|
36 | #include <time/timeout.h> |
37 | #include <time/timeout.h> |
37 | #include <arch.h> |
38 | #include <arch.h> |
38 | #include <context.h> |
39 | #include <context.h> |
39 | #include <list.h> |
40 | #include <list.h> |
40 | 41 | ||
Line 65... | Line 66... | ||
65 | */ |
66 | */ |
66 | void waitq_interrupted_sleep(void *data) |
67 | void waitq_interrupted_sleep(void *data) |
67 | { |
68 | { |
68 | thread_t *t = (thread_t *) data; |
69 | thread_t *t = (thread_t *) data; |
69 | waitq_t *wq; |
70 | waitq_t *wq; |
70 | int do_wakeup = 0; |
71 | bool do_wakeup = false; |
71 | 72 | ||
72 | spinlock_lock(&threads_lock); |
73 | spinlock_lock(&threads_lock); |
73 | if (!list_member(&t->threads_link, &threads_head)) |
74 | if (!list_member(&t->threads_link, &threads_head)) |
74 | goto out; |
75 | goto out; |
75 | 76 | ||
76 | grab_locks: |
77 | grab_locks: |
77 | spinlock_lock(&t->lock); |
78 | spinlock_lock(&t->lock); |
78 | if (wq = t->sleep_queue) { |
79 | if (wq = t->sleep_queue) { /* assignment */ |
79 | if (!spinlock_trylock(&wq->lock)) { |
80 | if (!spinlock_trylock(&wq->lock)) { |
80 | spinlock_unlock(&t->lock); |
81 | spinlock_unlock(&t->lock); |
81 | goto grab_locks; /* avoid deadlock */ |
82 | goto grab_locks; /* avoid deadlock */ |
82 | } |
83 | } |
83 | 84 | ||
84 | list_remove(&t->wq_link); |
85 | list_remove(&t->wq_link); |
85 | t->saved_context = t->sleep_timeout_context; |
86 | t->saved_context = t->sleep_timeout_context; |
86 | do_wakeup = 1; |
87 | do_wakeup = true; |
87 | 88 | ||
88 | spinlock_unlock(&wq->lock); |
89 | spinlock_unlock(&wq->lock); |
89 | t->sleep_queue = NULL; |
90 | t->sleep_queue = NULL; |
90 | } |
91 | } |
91 | 92 | ||
92 | t->timeout_pending = 0; |
93 | t->timeout_pending = false; |
93 | spinlock_unlock(&t->lock); |
94 | spinlock_unlock(&t->lock); |
94 | 95 | ||
- | 96 | if (do_wakeup) |
|
95 | if (do_wakeup) thread_ready(t); |
97 | thread_ready(t); |
96 | 98 | ||
97 | out: |
99 | out: |
98 | spinlock_unlock(&threads_lock); |
100 | spinlock_unlock(&threads_lock); |
99 | } |
101 | } |
100 | 102 | ||
Line 191... | Line 193... | ||
191 | before_thread_runs(); |
193 | before_thread_runs(); |
192 | spinlock_unlock(&THREAD->lock); |
194 | spinlock_unlock(&THREAD->lock); |
193 | interrupts_restore(ipl); |
195 | interrupts_restore(ipl); |
194 | return ESYNCH_TIMEOUT; |
196 | return ESYNCH_TIMEOUT; |
195 | } |
197 | } |
196 | THREAD->timeout_pending = 1; |
198 | THREAD->timeout_pending = true; |
197 | timeout_register(&THREAD->sleep_timeout, (__u64) usec, waitq_interrupted_sleep, THREAD); |
199 | timeout_register(&THREAD->sleep_timeout, (__u64) usec, waitq_interrupted_sleep, THREAD); |
198 | } |
200 | } |
199 | 201 | ||
200 | list_append(&THREAD->wq_link, &wq->head); |
202 | list_append(&THREAD->wq_link, &wq->head); |
201 | 203 | ||
Line 225... | Line 227... | ||
225 | * |
227 | * |
226 | * @param wq Pointer to wait queue. |
228 | * @param wq Pointer to wait queue. |
227 | * @param all If this is non-zero, all sleeping threads |
229 | * @param all If this is non-zero, all sleeping threads |
228 | * will be woken up and missed count will be zeroed. |
230 | * will be woken up and missed count will be zeroed. |
229 | */ |
231 | */ |
230 | void waitq_wakeup(waitq_t *wq, int all) |
232 | void waitq_wakeup(waitq_t *wq, bool all) |
231 | { |
233 | { |
232 | ipl_t ipl; |
234 | ipl_t ipl; |
233 | 235 | ||
234 | ipl = interrupts_disable(); |
236 | ipl = interrupts_disable(); |
235 | spinlock_lock(&wq->lock); |
237 | spinlock_lock(&wq->lock); |
Line 248... | Line 250... | ||
248 | * |
250 | * |
249 | * @param wq Pointer to wait queue. |
251 | * @param wq Pointer to wait queue. |
250 | * @param all If this is non-zero, all sleeping threads |
252 | * @param all If this is non-zero, all sleeping threads |
251 | * will be woken up and missed count will be zeroed. |
253 | * will be woken up and missed count will be zeroed. |
252 | */ |
254 | */ |
253 | void _waitq_wakeup_unsafe(waitq_t *wq, int all) |
255 | void _waitq_wakeup_unsafe(waitq_t *wq, bool all) |
254 | { |
256 | { |
255 | thread_t *t; |
257 | thread_t *t; |
256 | 258 | ||
257 | loop: |
259 | loop: |
258 | if (list_empty(&wq->head)) { |
260 | if (list_empty(&wq->head)) { |
259 | wq->missed_wakeups++; |
261 | wq->missed_wakeups++; |
- | 262 | if (all) |
|
260 | if (all) wq->missed_wakeups = 0; |
263 | wq->missed_wakeups = 0; |
261 | return; |
264 | return; |
262 | } |
265 | } |
263 | 266 | ||
264 | t = list_get_instance(wq->head.next, thread_t, wq_link); |
267 | t = list_get_instance(wq->head.next, thread_t, wq_link); |
265 | 268 | ||
266 | list_remove(&t->wq_link); |
269 | list_remove(&t->wq_link); |
267 | spinlock_lock(&t->lock); |
270 | spinlock_lock(&t->lock); |
268 | if (t->timeout_pending && timeout_unregister(&t->sleep_timeout)) |
271 | if (t->timeout_pending && timeout_unregister(&t->sleep_timeout)) |
269 | t->timeout_pending = 0; |
272 | t->timeout_pending = false; |
270 | t->sleep_queue = NULL; |
273 | t->sleep_queue = NULL; |
271 | spinlock_unlock(&t->lock); |
274 | spinlock_unlock(&t->lock); |
272 | 275 | ||
273 | thread_ready(t); |
276 | thread_ready(t); |
274 | 277 | ||
- | 278 | if (all) |
|
275 | if (all) goto loop; |
279 | goto loop; |
276 | } |
280 | } |