summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_synch.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/kern_synch.c')
-rw-r--r--sys/kern/kern_synch.c23
1 files changed, 19 insertions, 4 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();
OpenPOWER on IntegriCloud