32#include "opt_ktrace.h"
36#include <sys/limits.h>
40#include <sys/kernel.h>
42#include <sys/condvar.h>
44#include <sys/signalvar.h>
45#include <sys/sleepqueue.h>
46#include <sys/resourcevar.h>
49#include <sys/ktrace.h>
56#define CV_WAITERS_BOUND INT_MAX
58#define CV_WAITERS_INC(cvp) do { \
59 if ((cvp)->cv_waiters < CV_WAITERS_BOUND) \
60 (cvp)->cv_waiters++; \
66#define CV_ASSERT(cvp, lock, td) do { \
67 KASSERT((td) != NULL, ("%s: td NULL", __func__)); \
68 KASSERT(TD_IS_RUNNING(td), ("%s: not TDS_RUNNING", __func__)); \
69 KASSERT((cvp) != NULL, ("%s: cvp NULL", __func__)); \
70 KASSERT((lock) != NULL, ("%s: lock NULL", __func__)); \
80 cvp->cv_description = desc;
97 KASSERT(sq == NULL, (
"%s: associated sleep queue non-empty", __func__));
111 WITNESS_SAVE_DECL(lock_witness);
112 struct lock_class *
class;
114 uintptr_t lock_state;
119 if (KTRPOINT(td, KTR_CSW))
120 ktrcsw(1, 0, cv_wmesg(cvp));
123 WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, lock,
124 "Waiting on \"%s\"", cvp->cv_description);
125 class = LOCK_CLASS(lock);
127 if (SCHEDULER_STOPPED_TD(td))
133 if (lock == &
Giant.lock_object)
134 mtx_assert(&
Giant, MA_OWNED);
137 sleepq_add(cvp, lock, cvp->cv_description, SLEEPQ_CONDVAR, 0);
138 if (lock != &
Giant.lock_object) {
139 if (class->lc_flags & LC_SLEEPABLE)
141 WITNESS_SAVE(lock, lock_witness);
142 lock_state =
class->lc_unlock(lock);
143 if (class->lc_flags & LC_SLEEPABLE)
149 if (KTRPOINT(td, KTR_CSW))
150 ktrcsw(0, 0, cv_wmesg(cvp));
153 if (lock != &
Giant.lock_object) {
154 class->lc_lock(lock, lock_state);
155 WITNESS_RESTORE(lock, lock_witness);
166 struct lock_class *
class;
171 if (KTRPOINT(td, KTR_CSW))
172 ktrcsw(1, 0, cv_wmesg(cvp));
175 WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, lock,
176 "Waiting on \"%s\"", cvp->cv_description);
177 KASSERT(lock != &
Giant.lock_object,
178 (
"cv_wait_unlock cannot be used with Giant"));
179 class = LOCK_CLASS(lock);
181 if (SCHEDULER_STOPPED_TD(td)) {
182 class->lc_unlock(lock);
191 sleepq_add(cvp, lock, cvp->cv_description, SLEEPQ_CONDVAR, 0);
192 if (class->lc_flags & LC_SLEEPABLE)
194 class->lc_unlock(lock);
195 if (class->lc_flags & LC_SLEEPABLE)
200 if (KTRPOINT(td, KTR_CSW))
201 ktrcsw(0, 0, cv_wmesg(cvp));
215 WITNESS_SAVE_DECL(lock_witness);
216 struct lock_class *
class;
218 uintptr_t lock_state;
224 if (KTRPOINT(td, KTR_CSW))
225 ktrcsw(1, 0, cv_wmesg(cvp));
228 WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, lock,
229 "Waiting on \"%s\"", cvp->cv_description);
230 class = LOCK_CLASS(lock);
232 if (SCHEDULER_STOPPED_TD(td))
238 if (lock == &
Giant.lock_object)
239 mtx_assert(&
Giant, MA_OWNED);
242 sleepq_add(cvp, lock, cvp->cv_description, SLEEPQ_CONDVAR |
243 SLEEPQ_INTERRUPTIBLE, 0);
244 if (lock != &
Giant.lock_object) {
245 if (class->lc_flags & LC_SLEEPABLE)
247 WITNESS_SAVE(lock, lock_witness);
248 lock_state =
class->lc_unlock(lock);
249 if (class->lc_flags & LC_SLEEPABLE)
255 if (KTRPOINT(td, KTR_CSW))
256 ktrcsw(0, 0, cv_wmesg(cvp));
259 if (lock != &
Giant.lock_object) {
260 class->lc_lock(lock, lock_state);
261 WITNESS_RESTORE(lock, lock_witness);
276 WITNESS_SAVE_DECL(lock_witness);
277 struct lock_class *
class;
279 int lock_state, rval;
284 if (KTRPOINT(td, KTR_CSW))
285 ktrcsw(1, 0, cv_wmesg(cvp));
288 WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, lock,
289 "Waiting on \"%s\"", cvp->cv_description);
290 class = LOCK_CLASS(lock);
292 if (SCHEDULER_STOPPED_TD(td))
298 if (lock == &
Giant.lock_object)
299 mtx_assert(&
Giant, MA_OWNED);
302 sleepq_add(cvp, lock, cvp->cv_description, SLEEPQ_CONDVAR, 0);
304 if (lock != &
Giant.lock_object) {
305 if (class->lc_flags & LC_SLEEPABLE)
307 WITNESS_SAVE(lock, lock_witness);
308 lock_state =
class->lc_unlock(lock);
309 if (class->lc_flags & LC_SLEEPABLE)
315 if (KTRPOINT(td, KTR_CSW))
316 ktrcsw(0, 0, cv_wmesg(cvp));
319 if (lock != &
Giant.lock_object) {
320 class->lc_lock(lock, lock_state);
321 WITNESS_RESTORE(lock, lock_witness);
336 sbintime_t sbt, sbintime_t
pr,
int flags)
338 WITNESS_SAVE_DECL(lock_witness);
339 struct lock_class *
class;
341 int lock_state, rval;
346 if (KTRPOINT(td, KTR_CSW))
347 ktrcsw(1, 0, cv_wmesg(cvp));
350 WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, lock,
351 "Waiting on \"%s\"", cvp->cv_description);
352 class = LOCK_CLASS(lock);
354 if (SCHEDULER_STOPPED_TD(td))
360 if (lock == &
Giant.lock_object)
361 mtx_assert(&
Giant, MA_OWNED);
364 sleepq_add(cvp, lock, cvp->cv_description, SLEEPQ_CONDVAR |
365 SLEEPQ_INTERRUPTIBLE, 0);
367 if (lock != &
Giant.lock_object) {
368 if (class->lc_flags & LC_SLEEPABLE)
370 WITNESS_SAVE(lock, lock_witness);
371 lock_state =
class->lc_unlock(lock);
372 if (class->lc_flags & LC_SLEEPABLE)
378 if (KTRPOINT(td, KTR_CSW))
379 ktrcsw(0, 0, cv_wmesg(cvp));
382 if (lock != &
Giant.lock_object) {
383 class->lc_lock(lock, lock_state);
384 WITNESS_RESTORE(lock, lock_witness);
401 if (cvp->cv_waiters == 0)
404 if (cvp->cv_waiters == 0) {
428 if (cvp->cv_waiters == 0)
438 if (cvp->cv_waiters > 0) {
void cv_init(struct cv *cvp, const char *desc)
void cv_destroy(struct cv *cvp)
void _cv_wait_unlock(struct cv *cvp, struct lock_object *lock)
void _cv_wait(struct cv *cvp, struct lock_object *lock)
int _cv_timedwait_sbt(struct cv *cvp, struct lock_object *lock, sbintime_t sbt, sbintime_t pr, int flags)
void cv_signal(struct cv *cvp)
int _cv_timedwait_sig_sbt(struct cv *cvp, struct lock_object *lock, sbintime_t sbt, sbintime_t pr, int flags)
#define CV_WAITERS_INC(cvp)
int _cv_wait_sig(struct cv *cvp, struct lock_object *lock)
#define CV_ASSERT(cvp, lock, td)
void cv_broadcastpri(struct cv *cvp, int pri)
struct mtx __exclusive_cache_line Giant
static struct pollrec pr[POLL_LIST_LEN]
void sleepq_release(const void *wchan)
struct sleepqueue * sleepq_lookup(const void *wchan)
int sleepq_wait_sig(const void *wchan, int pri)
int sleepq_broadcast(const void *wchan, int flags, int pri, int queue)
int sleepq_timedwait_sig(const void *wchan, int pri)
int sleepq_signal(const void *wchan, int flags, int pri, int queue)
int sleepq_timedwait(const void *wchan, int pri)
void sleepq_add(const void *wchan, struct lock_object *lock, const char *wmesg, int flags, int queue)
void sleepq_set_timeout_sbt(const void *wchan, sbintime_t sbt, sbintime_t pr, int flags)
void sleepq_wait(const void *wchan, int pri)
void sleepq_lock(const void *wchan)