Rev 2131 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2131 | Rev 2422 | ||
---|---|---|---|
Line 84... | Line 84... | ||
84 | void waitq_timeouted_sleep(void *data) |
84 | void waitq_timeouted_sleep(void *data) |
85 | { |
85 | { |
86 | thread_t *t = (thread_t *) data; |
86 | thread_t *t = (thread_t *) data; |
87 | waitq_t *wq; |
87 | waitq_t *wq; |
88 | bool do_wakeup = false; |
88 | bool do_wakeup = false; |
- | 89 | DEADLOCK_PROBE_INIT(p_wqlock); |
|
89 | 90 | ||
90 | spinlock_lock(&threads_lock); |
91 | spinlock_lock(&threads_lock); |
91 | if (!thread_exists(t)) |
92 | if (!thread_exists(t)) |
92 | goto out; |
93 | goto out; |
93 | 94 | ||
94 | grab_locks: |
95 | grab_locks: |
95 | spinlock_lock(&t->lock); |
96 | spinlock_lock(&t->lock); |
96 | if ((wq = t->sleep_queue)) { /* assignment */ |
97 | if ((wq = t->sleep_queue)) { /* assignment */ |
97 | if (!spinlock_trylock(&wq->lock)) { |
98 | if (!spinlock_trylock(&wq->lock)) { |
98 | spinlock_unlock(&t->lock); |
99 | spinlock_unlock(&t->lock); |
- | 100 | DEADLOCK_PROBE(p_wqlock, DEADLOCK_THRESHOLD); |
|
99 | goto grab_locks; /* avoid deadlock */ |
101 | goto grab_locks; /* avoid deadlock */ |
100 | } |
102 | } |
101 | 103 | ||
102 | list_remove(&t->wq_link); |
104 | list_remove(&t->wq_link); |
103 | t->saved_context = t->sleep_timeout_context; |
105 | t->saved_context = t->sleep_timeout_context; |
Line 126... | Line 128... | ||
126 | void waitq_interrupt_sleep(thread_t *t) |
128 | void waitq_interrupt_sleep(thread_t *t) |
127 | { |
129 | { |
128 | waitq_t *wq; |
130 | waitq_t *wq; |
129 | bool do_wakeup = false; |
131 | bool do_wakeup = false; |
130 | ipl_t ipl; |
132 | ipl_t ipl; |
- | 133 | DEADLOCK_PROBE_INIT(p_wqlock); |
|
131 | 134 | ||
132 | ipl = interrupts_disable(); |
135 | ipl = interrupts_disable(); |
133 | spinlock_lock(&threads_lock); |
136 | spinlock_lock(&threads_lock); |
134 | if (!thread_exists(t)) |
137 | if (!thread_exists(t)) |
135 | goto out; |
138 | goto out; |
Line 145... | Line 148... | ||
145 | goto out; |
148 | goto out; |
146 | } |
149 | } |
147 | 150 | ||
148 | if (!spinlock_trylock(&wq->lock)) { |
151 | if (!spinlock_trylock(&wq->lock)) { |
149 | spinlock_unlock(&t->lock); |
152 | spinlock_unlock(&t->lock); |
- | 153 | DEADLOCK_PROBE(p_wqlock, DEADLOCK_THRESHOLD); |
|
150 | goto grab_locks; /* avoid deadlock */ |
154 | goto grab_locks; /* avoid deadlock */ |
151 | } |
155 | } |
152 | 156 | ||
153 | if (t->timeout_pending && timeout_unregister(&t->sleep_timeout)) |
157 | if (t->timeout_pending && timeout_unregister(&t->sleep_timeout)) |
154 | t->timeout_pending = false; |
158 | t->timeout_pending = false; |
Line 377... | Line 381... | ||
377 | * wrapper meant for general use. |
381 | * wrapper meant for general use. |
378 | * |
382 | * |
379 | * Besides its 'normal' wakeup operation, it attempts to unregister possible |
383 | * Besides its 'normal' wakeup operation, it attempts to unregister possible |
380 | * timeout. |
384 | * timeout. |
381 | * |
385 | * |
382 | * @param wq Pointer to wait queue. |
386 | * @param wq Pointer to wait queue. |
383 | * @param all If this is non-zero, all sleeping threads will be woken up and |
- | |
384 | * missed count will be zeroed. |
387 | * @param mode Wakeup mode. |
385 | */ |
388 | */ |
386 | void waitq_wakeup(waitq_t *wq, bool all) |
389 | void waitq_wakeup(waitq_t *wq, wakeup_mode_t mode) |
387 | { |
390 | { |
388 | ipl_t ipl; |
391 | ipl_t ipl; |
389 | 392 | ||
390 | ipl = interrupts_disable(); |
393 | ipl = interrupts_disable(); |
391 | spinlock_lock(&wq->lock); |
394 | spinlock_lock(&wq->lock); |
392 | 395 | ||
393 | _waitq_wakeup_unsafe(wq, all); |
396 | _waitq_wakeup_unsafe(wq, mode); |
394 | 397 | ||
395 | spinlock_unlock(&wq->lock); |
398 | spinlock_unlock(&wq->lock); |
396 | interrupts_restore(ipl); |
399 | interrupts_restore(ipl); |
397 | } |
400 | } |
398 | 401 | ||
399 | /** Internal SMP- and IRQ-unsafe version of waitq_wakeup() |
402 | /** Internal SMP- and IRQ-unsafe version of waitq_wakeup() |
400 | * |
403 | * |
401 | * This is the internal SMP- and IRQ-unsafe version of waitq_wakeup(). It |
404 | * This is the internal SMP- and IRQ-unsafe version of waitq_wakeup(). It |
402 | * assumes wq->lock is already locked and interrupts are already disabled. |
405 | * assumes wq->lock is already locked and interrupts are already disabled. |
403 | * |
406 | * |
404 | * @param wq Pointer to wait queue. |
407 | * @param wq Pointer to wait queue. |
405 | * @param all If this is non-zero, all sleeping threads will be woken up and |
408 | * @param mode If mode is WAKEUP_FIRST, then the longest waiting thread, |
- | 409 | * if any, is woken up. If mode is WAKEUP_ALL, then all |
|
- | 410 | * waiting threads, if any, are woken up. If there are no |
|
- | 411 | * waiting threads to be woken up, the missed wakeup is |
|
406 | * missed count will be zeroed. |
412 | * recorded in the wait queue. |
407 | */ |
413 | */ |
408 | void _waitq_wakeup_unsafe(waitq_t *wq, bool all) |
414 | void _waitq_wakeup_unsafe(waitq_t *wq, wakeup_mode_t mode) |
409 | { |
415 | { |
410 | thread_t *t; |
416 | thread_t *t; |
- | 417 | count_t count = 0; |
|
411 | 418 | ||
412 | loop: |
419 | loop: |
413 | if (list_empty(&wq->head)) { |
420 | if (list_empty(&wq->head)) { |
414 | wq->missed_wakeups++; |
421 | wq->missed_wakeups++; |
415 | if (all) |
422 | if (count && mode == WAKEUP_ALL) |
416 | wq->missed_wakeups = 0; |
423 | wq->missed_wakeups--; |
417 | return; |
424 | return; |
418 | } |
425 | } |
419 | 426 | ||
- | 427 | count++; |
|
420 | t = list_get_instance(wq->head.next, thread_t, wq_link); |
428 | t = list_get_instance(wq->head.next, thread_t, wq_link); |
421 | 429 | ||
422 | /* |
430 | /* |
423 | * Lock the thread prior to removing it from the wq. |
431 | * Lock the thread prior to removing it from the wq. |
424 | * This is not necessary because of mutual exclusion |
432 | * This is not necessary because of mutual exclusion |
Line 443... | Line 451... | ||
443 | t->sleep_queue = NULL; |
451 | t->sleep_queue = NULL; |
444 | spinlock_unlock(&t->lock); |
452 | spinlock_unlock(&t->lock); |
445 | 453 | ||
446 | thread_ready(t); |
454 | thread_ready(t); |
447 | 455 | ||
448 | if (all) |
456 | if (mode == WAKEUP_ALL) |
449 | goto loop; |
457 | goto loop; |
450 | } |
458 | } |
451 | 459 | ||
452 | /** @} |
460 | /** @} |
453 | */ |
461 | */ |