* Resumes a specific thread from the sleep queue associated with a specific * wait channel if it is on that queue. */
| 1052 | * wait channel if it is on that queue. |
| 1053 | */ |
| 1054 | void |
| 1055 | sleepq_remove(struct thread *td, const void *wchan) |
| 1056 | { |
| 1057 | struct sleepqueue_chain *sc; |
| 1058 | struct sleepqueue *sq; |
| 1059 | int wakeup_swapper; |
| 1060 | |
| 1061 | /* |
| 1062 | * Look up the sleep queue for this wait channel, then re-check |
| 1063 | * that the thread is asleep on that channel, if it is not, then |
| 1064 | * bail. |
| 1065 | */ |
| 1066 | MPASS(wchan != NULL); |
| 1067 | sc = SC_LOOKUP(wchan); |
| 1068 | mtx_lock_spin(&sc->sc_lock); |
| 1069 | /* |
| 1070 | * We can not lock the thread here as it may be sleeping on a |
| 1071 | * different sleepq. However, holding the sleepq lock for this |
| 1072 | * wchan can guarantee that we do not miss a wakeup for this |
| 1073 | * channel. The asserts below will catch any false positives. |
| 1074 | */ |
| 1075 | if (!TD_ON_SLEEPQ(td) || td->td_wchan != wchan) { |
| 1076 | mtx_unlock_spin(&sc->sc_lock); |
| 1077 | return; |
| 1078 | } |
| 1079 | |
| 1080 | /* Thread is asleep on sleep queue sq, so wake it up. */ |
| 1081 | sq = sleepq_lookup(wchan); |
| 1082 | MPASS(sq != NULL); |
| 1083 | MPASS(td->td_wchan == wchan); |
| 1084 | wakeup_swapper = sleepq_resume_thread(sq, td, 0, 0); |
| 1085 | if (wakeup_swapper) |
| 1086 | kick_proc0(); |
| 1087 | } |
| 1088 | |
| 1089 | /* |
| 1090 | * Abort a thread as if an interrupt had occurred. Only abort |
nothing calls this directly
no test coverage detected