Add a new kernel sleep function pause(9). pause(9) is for places that

want an equivalent of DELAY(9) that sleeps instead of spins.  It accepts
a wmesg and a timeout and is not interrupted by signals.  It uses a private
wait channel that should never be woken up by wakeup(9) or wakeup_one(9).

Glanced at by:	phk
This commit is contained in:
John Baldwin 2007-02-23 16:22:09 +00:00
parent 80b7fd0f47
commit 37e80fcac2
5 changed files with 47 additions and 5 deletions

View File

@ -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

View File

@ -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

View File

@ -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;
@ -307,6 +311,22 @@ msleep_spin(ident, mtx, wmesg, timo)
return (rval);
}
/*
* 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.
*/

View File

@ -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);

View File

@ -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);