diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c index 0a9c27a..27eda2f 100644 --- a/sys/kern/kern_synch.c +++ b/sys/kern/kern_synch.c @@ -146,12 +146,12 @@ sleepinit(void) */ int _sleep(void *ident, struct lock_object *lock, int priority, - const char *wmesg, int timo) + const char *wmesg, sbintime_t sbt, sbintime_t pr, int flags) { struct thread *td; struct proc *p; struct lock_class *class; - int catch, flags, lock_state, pri, rval; + int catch, lock_state, pri, rval, sleepq_flags; WITNESS_SAVE_DECL(lock_witness); td = curthread; @@ -162,7 +162,7 @@ _sleep(void *ident, struct lock_object *lock, int priority, #endif WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, lock, "Sleeping on \"%s\"", wmesg); - KASSERT(timo != 0 || mtx_owned(&Giant) || lock != NULL, + KASSERT(sbt != 0 || mtx_owned(&Giant) || lock != NULL, ("sleeping without a lock")); KASSERT(p != NULL, ("msleep1")); KASSERT(ident != NULL && TD_IS_RUNNING(td), ("msleep")); @@ -199,13 +199,13 @@ _sleep(void *ident, struct lock_object *lock, int priority, sleepq_remove(td, td->td_wchan); if (ident == &pause_wchan) - flags = SLEEPQ_PAUSE; + sleepq_flags = SLEEPQ_PAUSE; else - flags = SLEEPQ_SLEEP; + sleepq_flags = SLEEPQ_SLEEP; if (catch) - flags |= SLEEPQ_INTERRUPTIBLE; + sleepq_flags |= SLEEPQ_INTERRUPTIBLE; if (priority & PBDRY) - flags |= SLEEPQ_STOP_ON_BDRY; + sleepq_flags |= SLEEPQ_STOP_ON_BDRY; sleepq_lock(ident); CTR5(KTR_PROC, "sleep: thread %ld (pid %ld, %s) on %s (%p)", @@ -231,18 +231,18 @@ _sleep(void *ident, struct lock_object *lock, int priority, * stopped, then td will no longer be on a sleep queue upon * return from cursig(). */ - sleepq_add(ident, lock, wmesg, flags, 0); - if (timo) - sleepq_set_timeout(ident, timo); + sleepq_add(ident, lock, wmesg, sleepq_flags, 0); + if (sbt != 0) + sleepq_set_timeout_sbt(ident, sbt, pr, flags); if (lock != NULL && class->lc_flags & LC_SLEEPABLE) { sleepq_release(ident); WITNESS_SAVE(lock, lock_witness); lock_state = class->lc_unlock(lock); sleepq_lock(ident); } - if (timo && catch) + if (sbt != 0 && catch) rval = sleepq_timedwait_sig(ident, pri); - else if (timo) + else if (sbt != 0) rval = sleepq_timedwait(ident, pri); else if (catch) rval = sleepq_wait_sig(ident, pri); @@ -263,7 +263,8 @@ _sleep(void *ident, struct lock_object *lock, int priority, } int -msleep_spin(void *ident, struct mtx *mtx, const char *wmesg, int timo) +msleep_spin_sbt(void *ident, struct mtx *mtx, const char *wmesg, + sbintime_t sbt, sbintime_t pr, int flags) { struct thread *td; struct proc *p; @@ -301,8 +302,8 @@ msleep_spin(void *ident, struct mtx *mtx, const char *wmesg, int timo) * We put ourselves on the sleep queue and start our timeout. */ sleepq_add(ident, &mtx->lock_object, wmesg, SLEEPQ_SLEEP, 0); - if (timo) - sleepq_set_timeout(ident, timo); + if (sbt != 0) + sleepq_set_timeout_sbt(ident, sbt, pr, flags); /* * Can't call ktrace with any spin locks held so it can lock the @@ -324,7 +325,7 @@ msleep_spin(void *ident, struct mtx *mtx, const char *wmesg, int timo) wmesg); sleepq_lock(ident); #endif - if (timo) + if (sbt != 0) rval = sleepq_timedwait(ident, 0); else { sleepq_wait(ident, 0); @@ -348,28 +349,30 @@ msleep_spin(void *ident, struct mtx *mtx, const char *wmesg, int timo) * to a "timo" value of one. */ int -pause(const char *wmesg, int timo) +pause_sbt(const char *wmesg, sbintime_t sbt, sbintime_t pr, int flags) { - KASSERT(timo >= 0, ("pause: timo must be >= 0")); + int sbt_sec; + + sbt_sec = sbintime_getsec(sbt); + KASSERT(sbt_sec >= 0, ("pause: timo must be >= 0")); /* silently convert invalid timeouts */ - if (timo < 1) - timo = 1; + if (sbt == 0) + sbt = tick_sbt; if (cold) { /* - * We delay one HZ at a time to avoid overflowing the + * We delay one second at a time to avoid overflowing the * system specific DELAY() function(s): */ - while (timo >= hz) { + while (sbt_sec > 0) { DELAY(1000000); - timo -= hz; + sbt_sec--; } - if (timo > 0) - DELAY(timo * tick); + DELAY((sbt & 0xffffffff) / SBT_1US); return (0); } - return (tsleep(&pause_wchan, 0, wmesg, timo)); + return (_sleep(&pause_wchan, NULL, 0, wmesg, sbt, pr, flags)); } /* diff --git a/sys/sys/mutex.h b/sys/sys/mutex.h index 9a36b63..6f6c655 100644 --- a/sys/sys/mutex.h +++ b/sys/sys/mutex.h @@ -376,7 +376,8 @@ extern struct mtx_pool *mtxpool_sleep; mtx_assert_((m), (what), __FILE__, __LINE__) #define mtx_sleep(chan, mtx, pri, wmesg, timo) \ - _sleep((chan), &(mtx)->lock_object, (pri), (wmesg), (timo)) + _sleep((chan), &(mtx)->lock_object, (pri), (wmesg), \ + (tick_sbt * (timo)), 0, C_HARDCLOCK) #define mtx_initialized(m) lock_initalized(&(m)->lock_object) diff --git a/sys/sys/rwlock.h b/sys/sys/rwlock.h index 8623c05..0d98b57 100644 --- a/sys/sys/rwlock.h +++ b/sys/sys/rwlock.h @@ -211,7 +211,8 @@ void __rw_assert(const volatile uintptr_t *c, int what, const char *file, rw_runlock(rw); \ } while (0) #define rw_sleep(chan, rw, pri, wmesg, timo) \ - _sleep((chan), &(rw)->lock_object, (pri), (wmesg), (timo)) + _sleep((chan), &(rw)->lock_object, (pri), (wmesg), \ + (tick_sbt * (timo)), 0, C_HARDCLOCK) #define rw_initialized(rw) lock_initalized(&(rw)->lock_object) diff --git a/sys/sys/sx.h b/sys/sys/sx.h index 8c76a50..4db61d8 100644 --- a/sys/sys/sx.h +++ b/sys/sys/sx.h @@ -275,7 +275,8 @@ __sx_sunlock(struct sx *sx, const char *file, int line) #define sx_unlock(sx) sx_unlock_((sx), LOCK_FILE, LOCK_LINE) #define sx_sleep(chan, sx, pri, wmesg, timo) \ - _sleep((chan), &(sx)->lock_object, (pri), (wmesg), (timo)) + _sleep((chan), &(sx)->lock_object, (pri), (wmesg), \ + (tick_sbt * (timo)), 0, C_HARDCLOCK) /* * Options passed to sx_init_flags(). diff --git a/sys/sys/systm.h b/sys/sys/systm.h index 82881bd..9ee1766 100644 --- a/sys/sys/systm.h +++ b/sys/sys/systm.h @@ -347,14 +347,27 @@ static __inline void splx(intrmask_t ipl __unused) { return; } * less often. */ int _sleep(void *chan, struct lock_object *lock, int pri, const char *wmesg, - int timo) __nonnull(1); + sbintime_t sbt, sbintime_t pr, int flags) __nonnull(1); #define msleep(chan, mtx, pri, wmesg, timo) \ - _sleep((chan), &(mtx)->lock_object, (pri), (wmesg), (timo)) -int msleep_spin(void *chan, struct mtx *mtx, const char *wmesg, int timo) - __nonnull(1); -int pause(const char *wmesg, int timo); + _sleep((chan), &(mtx)->lock_object, (pri), (wmesg), \ + (tick_sbt * (timo)), 0, C_HARDCLOCK) +#define msleep_sbt(chan, mtx, pri, wmesg, bt, pr, flags) \ + _sleep((chan), &(mtx)->lock_object, (pri), (wmesg), (bt), (pr), \ + (flags)) +int msleep_spin_sbt(void *chan, struct mtx *mtx, const char *wmesg, + sbintime_t sbt, sbintime_t pr, int flags) __nonnull(1); +#define msleep_spin(chan, mtx, wmesg, timo) \ + msleep_spin_sbt((chan), (mtx), (wmesg), (tick_sbt * (timo)), \ + 0, C_HARDCLOCK) +int pause_sbt(const char *wmesg, sbintime_t sbt, sbintime_t pr, + int flags); +#define pause(wmesg, timo) \ + pause_sbt((wmesg), (tick_sbt * (timo)), 0, C_HARDCLOCK) #define tsleep(chan, pri, wmesg, timo) \ - _sleep((chan), NULL, (pri), (wmesg), (timo)) + _sleep((chan), NULL, (pri), (wmesg), (tick_sbt * (timo)), \ + 0, C_HARDCLOCK) +#define tsleep_sbt(chan, pri, wmesg, bt, pr, flags) \ + _sleep((chan), NULL, (pri), (wmesg), (bt), (pr), (flags)) void wakeup(void *chan) __nonnull(1); void wakeup_one(void *chan) __nonnull(1);