summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--share/man/man9/Makefile1
-rw-r--r--share/man/man9/sleep.927
-rw-r--r--sys/kern/kern_synch.c22
-rw-r--r--sys/sys/sleepqueue.h1
-rw-r--r--sys/sys/systm.h1
5 files changed, 47 insertions, 5 deletions
diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile
index 2298e39..64c11ab 100644
--- a/share/man/man9/Makefile
+++ b/share/man/man9/Makefile
@@ -997,6 +997,7 @@ MLINKS+=signal.9 cursig.9 \
signal.9 trapsignal.9
MLINKS+=sleep.9 msleep.9 \
sleep.9 msleep_spin.9 \
+ sleep.9 pause.9 \
sleep.9 tsleep.9 \
sleep.9 wakeup.9 \
sleep.9 wakeup_one.9
diff --git a/share/man/man9/sleep.9 b/share/man/man9/sleep.9
index db97565..0973fc5 100644
--- a/share/man/man9/sleep.9
+++ b/share/man/man9/sleep.9
@@ -31,6 +31,7 @@
.Sh NAME
.Nm msleep ,
.Nm msleep_spin ,
+.Nm pause ,
.Nm tsleep ,
.Nm wakeup
.Nd wait for events
@@ -39,12 +40,14 @@
.In sys/systm.h
.In sys/proc.h
.Ft int
-.Fn tsleep "void *chan" "int priority" "const char *wmesg" "int timo"
-.Ft int
.Fn msleep "void *chan" "struct mtx *mtx" "int priority" "const char *wmesg" "int timo"
.Ft int
.Fn msleep_spin "void *chan" "struct mtx *mtx" "const char *wmesg" "int timo"
.Ft void
+.Fn pause "const char *wmesg" "int timo"
+.Ft int
+.Fn tsleep "void *chan" "int priority" "const char *wmesg" "int timo"
+.Ft void
.Fn wakeup "void *chan"
.Ft void
.Fn wakeup_one "void *chan"
@@ -53,6 +56,7 @@ The functions
.Fn tsleep ,
.Fn msleep ,
.Fn msleep_spin ,
+.Fn pause ,
.Fn wakeup ,
and
.Fn wakeup_one
@@ -61,12 +65,13 @@ If a thread must wait for an
external event, it is put to sleep by
.Fn tsleep ,
.Fn msleep ,
+.Fn msleep_spin ,
or
-.Fn msleep_spin .
+.Fn pause .
The parameter
.Fa chan
is an arbitrary address that uniquely identifies the event on which
-the thread is being asleep.
+the thread is being put to sleep.
All threads sleeping on a single
.Fa chan
are woken up later by
@@ -184,6 +189,16 @@ and it does not support the
and
.Dv PCATCH
flags.
+.Pp
+The
+.Fn pause
+function is a wrapper around
+.Fn tsleep
+that suspends execution of the current thread for the indicated timeout.
+The thread can not be awakened early by signals or calls to
+.Fn wakeup
+or
+.Fn wakeup_one.
.Sh RETURN VALUES
See above.
.Sh SEE ALSO
@@ -211,6 +226,10 @@ function appeared in
and the
.Fn msleep_spin
function appeared in
+.Fx 6.2 .
+.The
+.Fn pause
+function appeared in
.Fx 7.0 .
.Pp
The
diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c
index 6cc7c70..089919c 100644
--- a/sys/kern/kern_synch.c
+++ b/sys/kern/kern_synch.c
@@ -69,6 +69,7 @@ SYSINIT(synch_setup, SI_SUB_KICK_SCHEDULER, SI_ORDER_FIRST, synch_setup, NULL)
int hogticks;
int lbolt;
+static int pause_wchan;
static struct callout loadav_callout;
static struct callout lbolt_callout;
@@ -164,7 +165,10 @@ msleep(ident, mtx, priority, wmesg, timo)
if (TD_ON_SLEEPQ(td))
sleepq_remove(td, td->td_wchan);
- flags = SLEEPQ_MSLEEP;
+ if (ident == &pause_wchan)
+ flags = SLEEPQ_PAUSE;
+ else
+ flags = SLEEPQ_MSLEEP;
if (catch)
flags |= SLEEPQ_INTERRUPTIBLE;
@@ -308,6 +312,22 @@ msleep_spin(ident, mtx, wmesg, timo)
}
/*
+ * pause() is like tsleep() except that the intention is to not be
+ * explicitly woken up by another thread. Instead, the current thread
+ * simply wishes to sleep until the timeout expires. It is
+ * implemented using a dummy wait channel.
+ */
+int
+pause(wmesg, timo)
+ const char *wmesg;
+ int timo;
+{
+
+ KASSERT(timo != 0, ("pause: timeout required"));
+ return (tsleep(&pause_wchan, 0, wmesg, timo));
+}
+
+/*
* Make all threads sleeping on the specified identifier runnable.
*/
void
diff --git a/sys/sys/sleepqueue.h b/sys/sys/sleepqueue.h
index 19a231d..15a673d 100644
--- a/sys/sys/sleepqueue.h
+++ b/sys/sys/sleepqueue.h
@@ -84,6 +84,7 @@ struct thread;
#define SLEEPQ_TYPE 0x0ff /* Mask of sleep queue types. */
#define SLEEPQ_MSLEEP 0x00 /* Used by msleep/wakeup. */
#define SLEEPQ_CONDVAR 0x01 /* Used for a cv. */
+#define SLEEPQ_PAUSE 0x02 /* Used by pause. */
#define SLEEPQ_INTERRUPTIBLE 0x100 /* Sleep is interruptible. */
void init_sleepqueues(void);
diff --git a/sys/sys/systm.h b/sys/sys/systm.h
index 6fa2bfa..09cfac9 100644
--- a/sys/sys/systm.h
+++ b/sys/sys/systm.h
@@ -310,6 +310,7 @@ static __inline void splx(intrmask_t ipl __unused) { return; }
int msleep(void *chan, struct mtx *mtx, int pri, const char *wmesg,
int timo);
int msleep_spin(void *chan, struct mtx *mtx, const char *wmesg, int timo);
+int pause(const char *wmesg, int timo);
#define tsleep(chan, pri, wmesg, timo) msleep(chan, NULL, pri, wmesg, timo)
void wakeup(void *chan) __nonnull(1);
void wakeup_one(void *chan) __nonnull(1);
OpenPOWER on IntegriCloud