* Wait on a condition variable. The current thread is placed on the condition * variable's wait queue and suspended. A cv_signal or cv_broadcast on the same * condition variable will resume the thread. The mutex is released before * sleeping and will be held on return. It is recommended that the mutex be * held when cv_signal or cv_broadcast are called. */
| 106 | * held when cv_signal or cv_broadcast are called. |
| 107 | */ |
| 108 | void |
| 109 | _cv_wait(struct cv *cvp, struct lock_object *lock) |
| 110 | { |
| 111 | WITNESS_SAVE_DECL(lock_witness); |
| 112 | struct lock_class *class; |
| 113 | struct thread *td; |
| 114 | uintptr_t lock_state; |
| 115 | |
| 116 | td = curthread; |
| 117 | lock_state = 0; |
| 118 | #ifdef KTRACE |
| 119 | if (KTRPOINT(td, KTR_CSW)) |
| 120 | ktrcsw(1, 0, cv_wmesg(cvp)); |
| 121 | #endif |
| 122 | CV_ASSERT(cvp, lock, td); |
| 123 | WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, lock, |
| 124 | "Waiting on \"%s\"", cvp->cv_description); |
| 125 | class = LOCK_CLASS(lock); |
| 126 | |
| 127 | if (SCHEDULER_STOPPED_TD(td)) |
| 128 | return; |
| 129 | |
| 130 | sleepq_lock(cvp); |
| 131 | |
| 132 | CV_WAITERS_INC(cvp); |
| 133 | if (lock == &Giant.lock_object) |
| 134 | mtx_assert(&Giant, MA_OWNED); |
| 135 | DROP_GIANT(); |
| 136 | |
| 137 | sleepq_add(cvp, lock, cvp->cv_description, SLEEPQ_CONDVAR, 0); |
| 138 | if (lock != &Giant.lock_object) { |
| 139 | if (class->lc_flags & LC_SLEEPABLE) |
| 140 | sleepq_release(cvp); |
| 141 | WITNESS_SAVE(lock, lock_witness); |
| 142 | lock_state = class->lc_unlock(lock); |
| 143 | if (class->lc_flags & LC_SLEEPABLE) |
| 144 | sleepq_lock(cvp); |
| 145 | } |
| 146 | sleepq_wait(cvp, 0); |
| 147 | |
| 148 | #ifdef KTRACE |
| 149 | if (KTRPOINT(td, KTR_CSW)) |
| 150 | ktrcsw(0, 0, cv_wmesg(cvp)); |
| 151 | #endif |
| 152 | PICKUP_GIANT(); |
| 153 | if (lock != &Giant.lock_object) { |
| 154 | class->lc_lock(lock, lock_state); |
| 155 | WITNESS_RESTORE(lock, lock_witness); |
| 156 | } |
| 157 | } |
| 158 | |
| 159 | /* |
| 160 | * Wait on a condition variable. This function differs from cv_wait by |
nothing calls this directly
no test coverage detected