summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/kern_synch.c23
-rw-r--r--sys/sys/param.h1
-rw-r--r--sys/sys/systm.h5
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));
OpenPOWER on IntegriCloud