Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/kern_condvar.c
Show First 20 Lines • Show All 204 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* Wait on a condition variable, allowing interruption by signals. Return 0 if | * Wait on a condition variable, allowing interruption by signals. Return 0 if | ||||
* the thread was resumed with cv_signal or cv_broadcast, EINTR or ERESTART if | * the thread was resumed with cv_signal or cv_broadcast, EINTR or ERESTART if | ||||
* a signal was caught. If ERESTART is returned the system call should be | * a signal was caught. If ERESTART is returned the system call should be | ||||
* restarted if possible. | * restarted if possible. | ||||
*/ | */ | ||||
int | int | ||||
_cv_wait_sig(struct cv *cvp, struct lock_object *lock) | _cv_wait_sig(struct cv *cvp, struct lock_object *lock, int flags) | ||||
{ | { | ||||
WITNESS_SAVE_DECL(lock_witness); | WITNESS_SAVE_DECL(lock_witness); | ||||
struct lock_class *class; | struct lock_class *class; | ||||
struct thread *td; | struct thread *td; | ||||
uintptr_t lock_state; | uintptr_t lock_state; | ||||
int rval; | int rval, sqflags; | ||||
MPASS((flags & ~(C_USERWAIT)) == 0); | |||||
td = curthread; | td = curthread; | ||||
lock_state = 0; | lock_state = 0; | ||||
#ifdef KTRACE | #ifdef KTRACE | ||||
if (KTRPOINT(td, KTR_CSW)) | if (KTRPOINT(td, KTR_CSW)) | ||||
ktrcsw(1, 0, cv_wmesg(cvp)); | ktrcsw(1, 0, cv_wmesg(cvp)); | ||||
#endif | #endif | ||||
CV_ASSERT(cvp, lock, td); | CV_ASSERT(cvp, lock, td); | ||||
WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, lock, | WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, lock, | ||||
"Waiting on \"%s\"", cvp->cv_description); | "Waiting on \"%s\"", cvp->cv_description); | ||||
class = LOCK_CLASS(lock); | class = LOCK_CLASS(lock); | ||||
if (SCHEDULER_STOPPED_TD(td)) | if (SCHEDULER_STOPPED_TD(td)) | ||||
return (0); | return (0); | ||||
sleepq_lock(cvp); | sleepq_lock(cvp); | ||||
CV_WAITERS_INC(cvp); | CV_WAITERS_INC(cvp); | ||||
if (lock == &Giant.lock_object) | if (lock == &Giant.lock_object) | ||||
mtx_assert(&Giant, MA_OWNED); | mtx_assert(&Giant, MA_OWNED); | ||||
DROP_GIANT(); | DROP_GIANT(); | ||||
sleepq_add(cvp, lock, cvp->cv_description, SLEEPQ_CONDVAR | | sqflags = SLEEPQ_CONDVAR | SLEEPQ_INTERRUPTIBLE; | ||||
SLEEPQ_INTERRUPTIBLE, 0); | if ((flags & C_USERWAIT) != 0) | ||||
sqflags |= SLEEPQ_USERWAIT; | |||||
sleepq_add(cvp, lock, cvp->cv_description, sqflags, 0); | |||||
if (lock != &Giant.lock_object) { | if (lock != &Giant.lock_object) { | ||||
if (class->lc_flags & LC_SLEEPABLE) | if (class->lc_flags & LC_SLEEPABLE) | ||||
sleepq_release(cvp); | sleepq_release(cvp); | ||||
WITNESS_SAVE(lock, lock_witness); | WITNESS_SAVE(lock, lock_witness); | ||||
lock_state = class->lc_unlock(lock); | lock_state = class->lc_unlock(lock); | ||||
if (class->lc_flags & LC_SLEEPABLE) | if (class->lc_flags & LC_SLEEPABLE) | ||||
sleepq_lock(cvp); | sleepq_lock(cvp); | ||||
} | } | ||||
Show All 20 Lines | |||||
int | int | ||||
_cv_timedwait_sbt(struct cv *cvp, struct lock_object *lock, sbintime_t sbt, | _cv_timedwait_sbt(struct cv *cvp, struct lock_object *lock, sbintime_t sbt, | ||||
sbintime_t pr, int flags) | sbintime_t pr, int flags) | ||||
{ | { | ||||
WITNESS_SAVE_DECL(lock_witness); | WITNESS_SAVE_DECL(lock_witness); | ||||
struct lock_class *class; | struct lock_class *class; | ||||
struct thread *td; | struct thread *td; | ||||
int lock_state, rval; | int lock_state, rval; | ||||
int sqflags; | |||||
td = curthread; | td = curthread; | ||||
lock_state = 0; | lock_state = 0; | ||||
#ifdef KTRACE | #ifdef KTRACE | ||||
if (KTRPOINT(td, KTR_CSW)) | if (KTRPOINT(td, KTR_CSW)) | ||||
ktrcsw(1, 0, cv_wmesg(cvp)); | ktrcsw(1, 0, cv_wmesg(cvp)); | ||||
#endif | #endif | ||||
CV_ASSERT(cvp, lock, td); | CV_ASSERT(cvp, lock, td); | ||||
WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, lock, | WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, lock, | ||||
"Waiting on \"%s\"", cvp->cv_description); | "Waiting on \"%s\"", cvp->cv_description); | ||||
class = LOCK_CLASS(lock); | class = LOCK_CLASS(lock); | ||||
if (SCHEDULER_STOPPED_TD(td)) | if (SCHEDULER_STOPPED_TD(td)) | ||||
return (0); | return (0); | ||||
sleepq_lock(cvp); | sleepq_lock(cvp); | ||||
CV_WAITERS_INC(cvp); | CV_WAITERS_INC(cvp); | ||||
if (lock == &Giant.lock_object) | if (lock == &Giant.lock_object) | ||||
mtx_assert(&Giant, MA_OWNED); | mtx_assert(&Giant, MA_OWNED); | ||||
DROP_GIANT(); | DROP_GIANT(); | ||||
sleepq_add(cvp, lock, cvp->cv_description, SLEEPQ_CONDVAR, 0); | sqflags = SLEEPQ_CONDVAR; | ||||
if ((flags & C_USERWAIT) != 0) | |||||
sqflags |= SLEEPQ_USERWAIT; | |||||
sleepq_add(cvp, lock, cvp->cv_description, sqflags, 0); | |||||
sleepq_set_timeout_sbt(cvp, sbt, pr, flags); | sleepq_set_timeout_sbt(cvp, sbt, pr, flags); | ||||
if (lock != &Giant.lock_object) { | if (lock != &Giant.lock_object) { | ||||
if (class->lc_flags & LC_SLEEPABLE) | if (class->lc_flags & LC_SLEEPABLE) | ||||
sleepq_release(cvp); | sleepq_release(cvp); | ||||
WITNESS_SAVE(lock, lock_witness); | WITNESS_SAVE(lock, lock_witness); | ||||
lock_state = class->lc_unlock(lock); | lock_state = class->lc_unlock(lock); | ||||
if (class->lc_flags & LC_SLEEPABLE) | if (class->lc_flags & LC_SLEEPABLE) | ||||
sleepq_lock(cvp); | sleepq_lock(cvp); | ||||
Show All 23 Lines | |||||
int | int | ||||
_cv_timedwait_sig_sbt(struct cv *cvp, struct lock_object *lock, | _cv_timedwait_sig_sbt(struct cv *cvp, struct lock_object *lock, | ||||
sbintime_t sbt, sbintime_t pr, int flags) | sbintime_t sbt, sbintime_t pr, int flags) | ||||
{ | { | ||||
WITNESS_SAVE_DECL(lock_witness); | WITNESS_SAVE_DECL(lock_witness); | ||||
struct lock_class *class; | struct lock_class *class; | ||||
struct thread *td; | struct thread *td; | ||||
int lock_state, rval; | int lock_state, rval; | ||||
int sqflags; | |||||
td = curthread; | td = curthread; | ||||
lock_state = 0; | lock_state = 0; | ||||
#ifdef KTRACE | #ifdef KTRACE | ||||
if (KTRPOINT(td, KTR_CSW)) | if (KTRPOINT(td, KTR_CSW)) | ||||
ktrcsw(1, 0, cv_wmesg(cvp)); | ktrcsw(1, 0, cv_wmesg(cvp)); | ||||
#endif | #endif | ||||
CV_ASSERT(cvp, lock, td); | CV_ASSERT(cvp, lock, td); | ||||
WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, lock, | WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, lock, | ||||
"Waiting on \"%s\"", cvp->cv_description); | "Waiting on \"%s\"", cvp->cv_description); | ||||
class = LOCK_CLASS(lock); | class = LOCK_CLASS(lock); | ||||
if (SCHEDULER_STOPPED_TD(td)) | if (SCHEDULER_STOPPED_TD(td)) | ||||
return (0); | return (0); | ||||
sleepq_lock(cvp); | sleepq_lock(cvp); | ||||
CV_WAITERS_INC(cvp); | CV_WAITERS_INC(cvp); | ||||
if (lock == &Giant.lock_object) | if (lock == &Giant.lock_object) | ||||
mtx_assert(&Giant, MA_OWNED); | mtx_assert(&Giant, MA_OWNED); | ||||
DROP_GIANT(); | DROP_GIANT(); | ||||
sleepq_add(cvp, lock, cvp->cv_description, SLEEPQ_CONDVAR | | sqflags = SLEEPQ_CONDVAR | SLEEPQ_INTERRUPTIBLE; | ||||
SLEEPQ_INTERRUPTIBLE, 0); | if ((flags & C_USERWAIT) != 0) | ||||
sqflags |= SLEEPQ_USERWAIT; | |||||
sleepq_add(cvp, lock, cvp->cv_description, sqflags, 0); | |||||
sleepq_set_timeout_sbt(cvp, sbt, pr, flags); | sleepq_set_timeout_sbt(cvp, sbt, pr, flags); | ||||
if (lock != &Giant.lock_object) { | if (lock != &Giant.lock_object) { | ||||
if (class->lc_flags & LC_SLEEPABLE) | if (class->lc_flags & LC_SLEEPABLE) | ||||
sleepq_release(cvp); | sleepq_release(cvp); | ||||
WITNESS_SAVE(lock, lock_witness); | WITNESS_SAVE(lock, lock_witness); | ||||
lock_state = class->lc_unlock(lock); | lock_state = class->lc_unlock(lock); | ||||
if (class->lc_flags & LC_SLEEPABLE) | if (class->lc_flags & LC_SLEEPABLE) | ||||
sleepq_lock(cvp); | sleepq_lock(cvp); | ||||
▲ Show 20 Lines • Show All 75 Lines • Show Last 20 Lines |