Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/kern_synch.c
Show First 20 Lines • Show All 207 Lines • ▼ Show 20 Lines | #endif | ||||
if (sbt != 0) | if (sbt != 0) | ||||
sleepq_set_timeout_sbt(ident, sbt, pr, flags); | sleepq_set_timeout_sbt(ident, sbt, pr, flags); | ||||
if (lock != NULL && class->lc_flags & LC_SLEEPABLE) { | if (lock != NULL && class->lc_flags & LC_SLEEPABLE) { | ||||
sleepq_release(ident); | sleepq_release(ident); | ||||
WITNESS_SAVE(lock, lock_witness); | WITNESS_SAVE(lock, lock_witness); | ||||
lock_state = class->lc_unlock(lock); | lock_state = class->lc_unlock(lock); | ||||
sleepq_lock(ident); | sleepq_lock(ident); | ||||
} | } | ||||
if (sbt != 0 && catch) | if (sbt != 0) { | ||||
if (priority & PRTCLK) { | |||||
kib: I think that the changes to _sleep() can be avoided at all. If we set td_rtcgen before msleep… | |||||
Not Done Inline ActionsI considered this, but I liked the fact that the result was communicated entirely by the return value. However, after a fresh look, I realize that testing td_rtcgen is fairly clean, especially since callers are already manipulating it. I have reverted all changes in this file. (I hope Phabricator still shows these comments...) vangyzen: I considered this, but I liked the fact that the result was communicated entirely by the return… | |||||
thread_lock(td); | |||||
td->td_flags |= TDF_SLEEPRTC; | |||||
thread_unlock(td); | |||||
} | |||||
if (catch) | |||||
rval = sleepq_timedwait_sig(ident, pri); | rval = sleepq_timedwait_sig(ident, pri); | ||||
else if (sbt != 0) | else | ||||
rval = sleepq_timedwait(ident, pri); | rval = sleepq_timedwait(ident, pri); | ||||
else if (catch) | if (priority & PRTCLK) { | ||||
thread_lock(td); | |||||
if (td->td_flags & TDF_SLEEPRTC) { | |||||
td->td_flags &= ~TDF_SLEEPRTC; | |||||
} else if (rval == 0) { | |||||
/* | |||||
* The thread was awoken by an adjustment of | |||||
* the real-time clock. It should read the | |||||
* RTC again and act on the new value. | |||||
*/ | |||||
rval = ERELOOKUP; | |||||
} | |||||
thread_unlock(td); | |||||
} | |||||
} else if (catch) { | |||||
rval = sleepq_wait_sig(ident, pri); | rval = sleepq_wait_sig(ident, pri); | ||||
else { | } else { | ||||
sleepq_wait(ident, pri); | sleepq_wait(ident, pri); | ||||
rval = 0; | rval = 0; | ||||
} | } | ||||
#ifdef KTRACE | #ifdef KTRACE | ||||
if (KTRPOINT(td, KTR_CSW)) | if (KTRPOINT(td, KTR_CSW)) | ||||
ktrcsw(0, 0, wmesg); | ktrcsw(0, 0, wmesg); | ||||
#endif | #endif | ||||
PICKUP_GIANT(); | PICKUP_GIANT(); | ||||
▲ Show 20 Lines • Show All 359 Lines • Show Last 20 Lines |
I think that the changes to _sleep() can be avoided at all. If we set td_rtcgen before msleep() call in umtxq_sleep() and get td_rtcgen == 0 after sleep, we are guaranteed that the thread was either aborted in sleeping_on_old_rtc(), or sleepq_switch() refused to put it on sleepq. So you can just test for td_rtcgen == 0 in umtxq_sleep() instead of ERELOOKUP.