MFcalloutng:
Introduce sbt variants of msleep(), msleep_spin(), pause(), tsleep() in the KPI, allowing to specify timeout in 'sbintime_t' rather than ticks. Sponsored by: Google Summer of Code 2012, iXsystems inc. Tested by: flo, marius, ian, markj, Fabian Keil
This commit is contained in:
parent
7395c58e52
commit
8374b0e141
@ -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));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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().
|
||||
|
@ -340,14 +340,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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user