diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/kern_synch.c | 23 | ||||
-rw-r--r-- | sys/sys/param.h | 1 | ||||
-rw-r--r-- | sys/sys/systm.h | 5 |
3 files changed, 24 insertions, 5 deletions
diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c index 6c53f8f..cd41140 100644 --- a/sys/kern/kern_synch.c +++ b/sys/kern/kern_synch.c @@ -408,10 +408,15 @@ sleepinit(void) * signal needs to be delivered, ERESTART is returned if the current system * call should be restarted if possible, and EINTR is returned if the system * call should be interrupted by the signal (return EINTR). + * + * The mutex argument is exited before the caller is suspended, and + * entered before msleep returns. If priority includes the PDROP + * flag the mutex is not entered before returning. */ int -tsleep(ident, priority, wmesg, timo) +msleep(ident, mtx, priority, wmesg, timo) void *ident; + mtx_t *mtx; int priority, timo; const char *wmesg; { @@ -419,14 +424,22 @@ tsleep(ident, priority, wmesg, timo) int s, sig, catch = priority & PCATCH; struct callout_handle thandle; int rval = 0; + WITNESS_SAVE_DECL(mtx); #ifdef KTRACE if (p && KTRPOINT(p, KTR_CSW)) ktrcsw(p->p_tracep, 1, 0); #endif - mtx_assert(&Giant, MA_OWNED); + WITNESS_SLEEP(0, mtx); mtx_enter(&sched_lock, MTX_SPIN); + if (mtx != NULL) { + WITNESS_SAVE(mtx, mtx); + mtx_exit(mtx, MTX_DEF | MTX_NOSWITCH); + if (priority & PDROP) + mtx = NULL; + } + s = splhigh(); if (cold || panicstr) { /* @@ -527,7 +540,10 @@ out: if (KTRPOINT(p, KTR_CSW)) ktrcsw(p->p_tracep, 0, 0); #endif - + if (mtx != NULL) { + mtx_enter(mtx, MTX_DEF); + WITNESS_RESTORE(mtx, mtx); + } return (rval); } @@ -600,7 +616,6 @@ await(int priority, int timo) int rval = 0; int s; - mtx_assert(&Giant, MA_OWNED); mtx_enter(&sched_lock, MTX_SPIN); s = splhigh(); diff --git a/sys/sys/param.h b/sys/sys/param.h index 9797feb..7ac0290 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -116,6 +116,7 @@ #define PRIMASK 0x0ff #define PCATCH 0x100 /* OR'd with pri for tsleep to check signals */ +#define PDROP 0x200 /* OR'd with pri to stop re-entry of interlock mutex */ #define NZERO 0 /* default "nice" */ diff --git a/sys/sys/systm.h b/sys/sys/systm.h index 0e8f9bb..bd4cda6 100644 --- a/sys/sys/systm.h +++ b/sys/sys/systm.h @@ -92,6 +92,7 @@ extern int bootverbose; /* nonzero to print verbose messages */ struct clockframe; struct malloc_type; +struct mtx; struct proc; struct timeval; struct tty; @@ -318,7 +319,9 @@ extern watchdog_tickle_fn wdog_tickler; * Common `proc' functions are declared here so that proc.h can be included * less often. */ -int tsleep __P((void *chan, int pri, const char *wmesg, int timo)); +int msleep __P((void *chan, struct mtx *mtx, int pri, const char *wmesg, + int timo)); +#define tsleep(chan, pri, wmesg, timo) msleep(chan, NULL, pri, wmesg, timo) int asleep __P((void *chan, int pri, const char *wmesg, int timo)); int await __P((int pri, int timo)); void wakeup __P((void *chan)); |