* Marks the pending sleep of the current thread as interruptible and * makes an initial check for pending signals before putting a thread * to sleep. Enters and exits with the thread lock held. Thread lock * may have transitioned from the sleepq lock to a run lock. */
| 500 | * may have transitioned from the sleepq lock to a run lock. |
| 501 | */ |
| 502 | static int |
| 503 | sleepq_catch_signals(const void *wchan, int pri) |
| 504 | { |
| 505 | struct thread *td; |
| 506 | struct sleepqueue_chain *sc; |
| 507 | struct sleepqueue *sq; |
| 508 | int ret; |
| 509 | |
| 510 | sc = SC_LOOKUP(wchan); |
| 511 | mtx_assert(&sc->sc_lock, MA_OWNED); |
| 512 | MPASS(wchan != NULL); |
| 513 | td = curthread; |
| 514 | |
| 515 | ret = sleepq_check_ast_sc_locked(td, sc); |
| 516 | THREAD_LOCK_ASSERT(td, MA_OWNED); |
| 517 | mtx_assert(&sc->sc_lock, MA_OWNED); |
| 518 | |
| 519 | if (ret == 0) { |
| 520 | /* |
| 521 | * No pending signals and no suspension requests found. |
| 522 | * Switch the thread off the cpu. |
| 523 | */ |
| 524 | sleepq_switch(wchan, pri); |
| 525 | } else { |
| 526 | /* |
| 527 | * There were pending signals and this thread is still |
| 528 | * on the sleep queue, remove it from the sleep queue. |
| 529 | */ |
| 530 | if (TD_ON_SLEEPQ(td)) { |
| 531 | sq = sleepq_lookup(wchan); |
| 532 | sleepq_remove_thread(sq, td); |
| 533 | } |
| 534 | MPASS(td->td_lock != &sc->sc_lock); |
| 535 | mtx_unlock_spin(&sc->sc_lock); |
| 536 | thread_unlock(td); |
| 537 | } |
| 538 | return (ret); |
| 539 | } |
| 540 | |
| 541 | /* |
| 542 | * Switches to another thread if we are still asleep on a sleep queue. |
no test coverage detected