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:
parent
80b7fd0f47
commit
37e80fcac2
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user