| 798 | } |
| 799 | |
| 800 | static void |
| 801 | sleepq_remove_thread(struct sleepqueue *sq, struct thread *td) |
| 802 | { |
| 803 | struct sleepqueue_chain *sc __unused; |
| 804 | |
| 805 | MPASS(td != NULL); |
| 806 | MPASS(sq->sq_wchan != NULL); |
| 807 | MPASS(td->td_wchan == sq->sq_wchan); |
| 808 | MPASS(td->td_sqqueue < NR_SLEEPQS && td->td_sqqueue >= 0); |
| 809 | THREAD_LOCK_ASSERT(td, MA_OWNED); |
| 810 | sc = SC_LOOKUP(sq->sq_wchan); |
| 811 | mtx_assert(&sc->sc_lock, MA_OWNED); |
| 812 | |
| 813 | SDT_PROBE2(sched, , , wakeup, td, td->td_proc); |
| 814 | |
| 815 | /* Remove the thread from the queue. */ |
| 816 | sq->sq_blockedcnt[td->td_sqqueue]--; |
| 817 | TAILQ_REMOVE(&sq->sq_blocked[td->td_sqqueue], td, td_slpq); |
| 818 | |
| 819 | /* |
| 820 | * Get a sleep queue for this thread. If this is the last waiter, |
| 821 | * use the queue itself and take it out of the chain, otherwise, |
| 822 | * remove a queue from the free list. |
| 823 | */ |
| 824 | if (LIST_EMPTY(&sq->sq_free)) { |
| 825 | td->td_sleepqueue = sq; |
| 826 | #ifdef INVARIANTS |
| 827 | sq->sq_wchan = NULL; |
| 828 | #endif |
| 829 | #ifdef SLEEPQUEUE_PROFILING |
| 830 | sc->sc_depth--; |
| 831 | #endif |
| 832 | } else |
| 833 | td->td_sleepqueue = LIST_FIRST(&sq->sq_free); |
| 834 | LIST_REMOVE(td->td_sleepqueue, sq_hash); |
| 835 | |
| 836 | if ((td->td_flags & TDF_TIMEOUT) == 0 && td->td_sleeptimo != 0) |
| 837 | /* |
| 838 | * We ignore the situation where timeout subsystem was |
| 839 | * unable to stop our callout. The struct thread is |
| 840 | * type-stable, the callout will use the correct |
| 841 | * memory when running. The checks of the |
| 842 | * td_sleeptimo value in this function and in |
| 843 | * sleepq_timeout() ensure that the thread does not |
| 844 | * get spurious wakeups, even if the callout was reset |
| 845 | * or thread reused. |
| 846 | */ |
| 847 | callout_stop(&td->td_slpcallout); |
| 848 | |
| 849 | td->td_wmesg = NULL; |
| 850 | td->td_wchan = NULL; |
| 851 | td->td_flags &= ~(TDF_SINTR | TDF_TIMEOUT); |
| 852 | |
| 853 | CTR3(KTR_PROC, "sleepq_wakeup: thread %p (pid %ld, %s)", |
| 854 | (void *)td, (long)td->td_proc->p_pid, td->td_name); |
| 855 | } |
| 856 | |
| 857 | #ifdef INVARIANTS |
no test coverage detected