sleepqueue(9)
NAME
- init_sleepqueues, sleepq_abort, sleepq_add, sleepq_alloc,
sleepq_broadcast, sleepq_calc_signal_retval,
- sleepq_catch_signals,
sleepq_free, sleepq_lock, sleepq_lookup, sleepq_release,
- sleepq_remove,
sleepq_signal, sleepq_set_timeout, sleepq_timedwait,
sleepq_timedwait_sig, sleepq_wait, sleepq_wait_sig - manage
- the queues of
sleeping threads
SYNOPSIS
#include <sys/param.h>
#include <sys/sleepqueue.h>
void
init_sleepqueues(void);
void
sleepq_abort(struct thread *td);
void
sleepq_add(void *wchan, struct mtx *lock, const char *wmesg,
int flags);
struct sleepqueue *
sleepq_alloc(void);
void
sleepq_broadcast(void *wchan, int flags, int pri);
int
sleepq_calc_signal_retval(int sig);
int
sleepq_catch_signals(void *wchan);
void
sleepq_free(struct sleepqueue *sq);
struct sleepqueue *
sleepq_lookup(void *wchan);
void
sleepq_lock(void *wchan);
void
sleepq_release(void *wchan);
void
sleepq_remove(struct thread *td, void *wchan);
void
sleepq_signal(void *wchan, int flags, int pri);
void
sleepq_set_timeout(void *wchan, int timo);
int
sleepq_timedwait(void *wchan);
int
sleepq_timedwait_sig(void *wchan, int signal_caught);
void
sleepq_wait(void *wchan);
int
sleepq_wait_sig(void *wchan);
DESCRIPTION
- Sleep queues provide a mechanism for suspending execution of
- a thread
until some condition is met. Each queue is associated with
- a specific
wait channel when it is active, and only one queue may be
- associated with
a wait channel at any given point in time. An active queue
- holds a list
of threads that are blocked on the associated wait channel.
- Threads that
are not blocked on a wait channel have an associated inac
- tive sleep
queue. When a thread blocks on a wait channel it donates
- its inactive
sleep queue to the wait channel. When a thread is resumed,
- the wait
channel that it was blocked on gives it an inactive sleep
- queue for later
use.
- The sleepq_alloc() function allocates an inactive sleep
- queue and is used
to assign a sleep queue to a thread during thread creation.
- The
sleepq_free() function frees the resources associated with
- an inactive
sleep queue and is used to free a queue during thread de
- struction.
- Active sleep queues are stored in a hash table hashed on the
- addresses
pointed to by wait channels. Each bucket in the hash table
- contains a
sleep queue chain. A sleep queue chain contains a spin mu
- tex and a list
of sleep queues that hash to that specific chain. Active
- sleep queues
are protected by their chain's spin mutex. The
- init_sleepqueues() function initializes the hash table of sleep queue chains.
- The sleepq_lock() function locks the sleep queue chain asso
- ciated with
wait channel wchan.
- The sleepq_lookup() returns a pointer to the currently ac
- tive sleep queue
for that wait channel associated with wchan or NULL if there
- is no active
sleep queue associated with argument wchan. It requires the
- sleep queue
chain associated with wchan to have been locked by a prior
- call to
sleepq_lock().
- The sleepq_release() function unlocks the sleep queue chain
- associated
with wchan() and is primarily useful when aborting a pending
- sleep
request before one of the wait functions is called.
- The sleepq_add() function places the current thread on the
- sleep queue
associated with the wait channel wchan. The sleep queue
- chain associated
with argument wchan must be locked by a prior call to
- sleepq_lock() when
this function is called. If a mutex is specified via the
- lock argument,
and if the kernel was compiled with options INVARIANTS, then
- the sleep
queue code will perform extra checks to ensure that the mu
- tex is used by
all threads sleeping on wchan. The wmesg parameter should
- be a short
description of wchan. The flags parameter is a bitmask con
- sisting of the
type of sleep queue being slept on and zero or more optional
- flags.
- There are currently two types of sleep queues:
- SLEEPQ_CONDVAR A sleep queue used to implement condi
- tion variables.
SLEEPQ_MSLEEP A sleep queue used to implement
- msleep(9), wakeup(9)
- and wakeup_one(9).
- There is currently only one optional flag:
- SLEEPQ_INTERRUPTIBLE The current thread is entering an
- interruptible
- sleep.
- A timeout on the sleep may be specified by calling
- sleepq_set_timeout()
after sleepq_add(). The wchan parameter should be the same
- value from
the preceding call to sleepq_add(), and the sleep queue
- chain associated
with wchan must have been locked by a prior call to
- sleepq_lock(). The
timo parameter should specify the timeout value in ticks.
- The current thread may be marked interruptible by calling
sleepq_catch_signals() with wchan set to the wait channel.
- This function
returns a signal number if there are any pending signals for
- the current
thread and 0 if there is not a pending signal. The sleep
- queue chain
associated with argument wchan should have been locked by a
- prior call to
sleepq_lock().
- Once the thread is ready to suspend, one of the wait func
- tions is called
to put the current thread to sleep until it is awakened and
- to context
switch to another thread. The sleepq_wait() function is
- used for noninterruptible sleeps that do not have a timeout. The
- sleepq_timedwait()
function is used for non-interruptible sleeps that have had
- a timeout set
via sleepq_set_timeout(). The sleepq_wait_sig() function is
- used for
interruptible sleeps that do not have a timeout. The
sleepq_timedwait_sig() function is used for interruptible
- sleeps that do
have a timeout set. The wchan argument to all of the wait
- functions is
the wait channel being slept on. The sleep queue chain as
- sociated with
argument wchan needs to have been locked with a prior call
- to
sleepq_lock(). The signal_caught parameter to
- sleepq_timedwait_sig()
specifies if a previous call to sleepq_catch_signals() found
- a pending
signal.
- When the thread is resumed, the wait functions return a non
- zero value if
the thread was awakened due to an interrupt other than a
- signal or a
timeout. If the sleep timed out, then EWOULDBLOCK is re
- turned. If the
sleep was interrupted by something other than a signal, then
- some other
return value will be returned. If zero is returned after
- resuming from
an interruptible sleep, then sleepq_calc_signal_retval()
- should be called
to determine if the sleep was interrupted by a signal. If
- so,
sleepq_calc_signal_retval() returns ERESTART if the inter
- rupting signal
is restartable and EINTR otherwise. If the sleep was not
- interrupted by
a signal, sleepq_calc_signal_retval() will return 0.
- A sleeping thread is normally resumed by the
- sleepq_broadcast() and
sleepq_signal() functions. The sleepq_signal() function
- awakens the
highest priority thread sleeping on a wait channel while
sleepq_broadcast() awakens all of the threads sleeping on a
- wait channel.
The wchan argument specifics which wait channel to awaken.
- The flags
argument must match the sleep queue type contained in the
- flags argument
passed to sleepq_add() by the threads sleeping on the wait
- channel. If
the pri argument does not equal -1, then each thread that is
- awakened
will have its priority raised to pri if it has a lower pri
- ority. The
sleep queue chain associated with argument wchan must be
- locked by a
prior call to sleepq_lock() before calling any of these
- functions.
- A thread in an interruptible sleep can be interrupted by an
- other thread
via the sleepq_abort() function. The td argument specifies
- the thread to
interrupt. An individual thread can also be awakened from
- sleeping on a
specific wait channel via the sleepq_remove() function. The
- td argument
specifies the thread to awaken and the wchan argument speci
- fies the wait
channel to awaken it from. If the thread td is not blocked
- on the the
wait channel wchan then this function will not do anything,
- even if the
thread is asleep on a different wait channel. This function
- should only
be used if one of the other functions above is not suffi
- cient. One possible use is waking up a specific thread from a widely
- shared sleep channel.
- The sleep queue interface is currently used to implement the
- msleep(9)
and condvar(9) interfaces. Almost all other code in the
- kernel should
use one of those interfaces rather than manipulating sleep
- queues
directly.
SEE ALSO
- condvar(9), msleep(9), runqueue(9), scheduler(9)
- BSD March 10, 2004