Rev 2308 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2308 | Rev 2315 | ||
---|---|---|---|
Line 381... | Line 381... | ||
381 | * wrapper meant for general use. |
381 | * wrapper meant for general use. |
382 | * |
382 | * |
383 | * Besides its 'normal' wakeup operation, it attempts to unregister possible |
383 | * Besides its 'normal' wakeup operation, it attempts to unregister possible |
384 | * timeout. |
384 | * timeout. |
385 | * |
385 | * |
386 | * @param wq Pointer to wait queue. |
386 | * @param wq Pointer to wait queue. |
387 | * @param all If this is WAKEUP_ALL, all sleeping threads will be woken up and |
- | |
388 | * missed count will be zeroed. WAKEUP_FIRST wakes up just one thread or |
- | |
389 | * increments the missed count. WAKEUP_ALL_INC_MISSED wakes up all sleeping threads |
- | |
390 | * or increments missed_wakeups if there aren't any |
387 | * @param mode Wakeup mode. |
391 | */ |
388 | */ |
392 | void waitq_wakeup(waitq_t *wq, int all) |
389 | void waitq_wakeup(waitq_t *wq, wakeup_mode_t mode) |
393 | { |
390 | { |
394 | ipl_t ipl; |
391 | ipl_t ipl; |
395 | 392 | ||
396 | ipl = interrupts_disable(); |
393 | ipl = interrupts_disable(); |
397 | spinlock_lock(&wq->lock); |
394 | spinlock_lock(&wq->lock); |
398 | 395 | ||
399 | _waitq_wakeup_unsafe(wq, all); |
396 | _waitq_wakeup_unsafe(wq, mode); |
400 | 397 | ||
401 | spinlock_unlock(&wq->lock); |
398 | spinlock_unlock(&wq->lock); |
402 | interrupts_restore(ipl); |
399 | interrupts_restore(ipl); |
403 | } |
400 | } |
404 | 401 | ||
405 | /** Internal SMP- and IRQ-unsafe version of waitq_wakeup() |
402 | /** Internal SMP- and IRQ-unsafe version of waitq_wakeup() |
406 | * |
403 | * |
407 | * 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 |
408 | * assumes wq->lock is already locked and interrupts are already disabled. |
405 | * assumes wq->lock is already locked and interrupts are already disabled. |
409 | * |
406 | * |
410 | * @param wq Pointer to wait queue. |
407 | * @param wq Pointer to wait queue. |
411 | * @param all If this is WAKEUP_ALL, all sleeping threads will be woken up and |
408 | * @param mode If mode is WAKEUP_FIRST, then the longest waiting thread, |
412 | * missed count will be zeroed. WAKEUP_FIRST wakes up just one thread or |
409 | * if any, is woken up. If mode is WAKEUP_ALL, then all |
413 | * increments the missed count. WAKEUP_ALL_INC_MISSED wakes up all sleeping threads |
410 | * waiting threads, if any, are woken up. If there are no |
414 | * or increments missed_wakeups if there aren't any |
411 | * waiting threads to be woken up, the missed wakeup is |
- | 412 | * recorded in the wait queue. |
|
415 | */ |
413 | */ |
416 | void _waitq_wakeup_unsafe(waitq_t *wq, int all) |
414 | void _waitq_wakeup_unsafe(waitq_t *wq, wakeup_mode_t mode) |
417 | { |
415 | { |
418 | thread_t *t; |
416 | thread_t *t; |
- | 417 | count_t count = 0; |
|
419 | 418 | ||
- | 419 | loop: |
|
420 | if (list_empty(&wq->head)) { |
420 | if (list_empty(&wq->head)) { |
421 | if (all == WAKEUP_ALL) |
- | |
422 | wq->missed_wakeups = 0; |
421 | wq->missed_wakeups++; |
423 | else |
422 | if (count && mode == WAKEUP_ALL) |
424 | wq->missed_wakeups++; |
423 | wq->missed_wakeups--; |
425 | return; |
424 | return; |
426 | } |
425 | } |
427 | loop: |
- | |
428 | 426 | ||
- | 427 | count++; |
|
429 | t = list_get_instance(wq->head.next, thread_t, wq_link); |
428 | t = list_get_instance(wq->head.next, thread_t, wq_link); |
430 | 429 | ||
431 | /* |
430 | /* |
432 | * Lock the thread prior to removing it from the wq. |
431 | * Lock the thread prior to removing it from the wq. |
433 | * This is not necessary because of mutual exclusion |
432 | * This is not necessary because of mutual exclusion |
Line 451... | Line 450... | ||
451 | t->timeout_pending = false; |
450 | t->timeout_pending = false; |
452 | t->sleep_queue = NULL; |
451 | t->sleep_queue = NULL; |
453 | spinlock_unlock(&t->lock); |
452 | spinlock_unlock(&t->lock); |
454 | 453 | ||
455 | thread_ready(t); |
454 | thread_ready(t); |
456 | if (list_empty(&wq->head)) { |
- | |
457 | return; |
- | |
458 | } |
455 | |
459 | if (all != WAKEUP_FIRST) |
456 | if (mode == WAKEUP_ALL) |
460 | goto loop; |
457 | goto loop; |
461 | } |
458 | } |
462 | 459 | ||
463 | /** @} |
460 | /** @} |
464 | */ |
461 | */ |