summaryrefslogtreecommitdiffstats
path: root/share/man/man9/sleepqueue.9
diff options
context:
space:
mode:
Diffstat (limited to 'share/man/man9/sleepqueue.9')
-rw-r--r--share/man/man9/sleepqueue.9425
1 files changed, 425 insertions, 0 deletions
diff --git a/share/man/man9/sleepqueue.9 b/share/man/man9/sleepqueue.9
new file mode 100644
index 0000000..8557b9f
--- /dev/null
+++ b/share/man/man9/sleepqueue.9
@@ -0,0 +1,425 @@
+.\" Copyright (c) 2000-2004 John H. Baldwin <jhb@FreeBSD.org>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd February 19, 2013
+.Dt SLEEPQUEUE 9
+.Os
+.Sh NAME
+.Nm init_sleepqueues ,
+.Nm sleepq_abort ,
+.Nm sleepq_add ,
+.Nm sleepq_alloc ,
+.Nm sleepq_broadcast ,
+.Nm sleepq_calc_signal_retval ,
+.Nm sleepq_catch_signals ,
+.Nm sleepq_free ,
+.Nm sleepq_lock ,
+.Nm sleepq_lookup ,
+.Nm sleepq_release ,
+.Nm sleepq_remove ,
+.Nm sleepq_signal ,
+.Nm sleepq_set_timeout ,
+.Nm sleepq_set_timeout_sbt ,
+.Nm sleepq_sleepcnt ,
+.Nm sleepq_timedwait ,
+.Nm sleepq_timedwait_sig ,
+.Nm sleepq_type ,
+.Nm sleepq_wait ,
+.Nm sleepq_wait_sig
+.Nd manage the queues of sleeping threads
+.Sh SYNOPSIS
+.In sys/param.h
+.In sys/sleepqueue.h
+.Ft void
+.Fn init_sleepqueues "void"
+.Ft int
+.Fn sleepq_abort "struct thread *td"
+.Ft void
+.Fn sleepq_add "void *wchan" "struct lock_object *lock" "const char *wmesg" "int flags" "int queue"
+.Ft struct sleepqueue *
+.Fn sleepq_alloc "void"
+.Ft int
+.Fn sleepq_broadcast "void *wchan" "int flags" "int pri" "int queue"
+.Ft int
+.Fn sleepq_calc_signal_retval "int sig"
+.Ft int
+.Fn sleepq_catch_signals "void *wchan"
+.Ft void
+.Fn sleepq_free "struct sleepqueue *sq"
+.Ft struct sleepqueue *
+.Fn sleepq_lookup "void *wchan"
+.Ft void
+.Fn sleepq_lock "void *wchan"
+.Ft void
+.Fn sleepq_release "void *wchan"
+.Ft void
+.Fn sleepq_remove "struct thread *td" "void *wchan"
+.Ft int
+.Fn sleepq_signal "void *wchan" "int flags" "int pri" "int queue"
+.Ft void
+.Fn sleepq_set_timeout "void *wchan" "int timo"
+.Ft void
+.Fn sleepq_set_timeout_sbt "void *wchan" "sbintime_t sbt" \
+"sbintime_t pr" "int flags"
+.Ft u_int
+.Fn sleepq_sleepcnt "void *wchan" "int queue"
+.Ft int
+.Fn sleepq_timedwait "void *wchan"
+.Ft int
+.Fn sleepq_timedwait_sig "void *wchan" "int signal_caught"
+.Ft int
+.Fn sleepq_type "void *wchan"
+.Ft void
+.Fn sleepq_wait "void *wchan"
+.Ft int
+.Fn sleepq_wait_sig "void *wchan"
+.Sh 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.
+The implementation of each wait channel splits its sleepqueue into 2 sub-queues
+in order to enable some optimizations on threads' wakeups.
+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 inactive
+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.
+.Pp
+The
+.Fn sleepq_alloc
+function allocates an inactive sleep queue and is used to assign a
+sleep queue to a thread during thread creation.
+The
+.Fn sleepq_free
+function frees the resources associated with an inactive sleep queue and is
+used to free a queue during thread destruction.
+.Pp
+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 mutex and a list of sleep queues that hash
+to that specific chain.
+Active sleep queues are protected by their chain's spin mutex.
+The
+.Fn init_sleepqueues
+function initializes the hash table of sleep queue chains.
+.Pp
+The
+.Fn sleepq_lock
+function locks the sleep queue chain associated with wait channel
+.Fa wchan .
+.Pp
+The
+.Fn sleepq_lookup
+returns a pointer to the currently active sleep queue for that wait
+channel associated with
+.Fa wchan
+or
+.Dv NULL
+if there is no active sleep queue associated with
+argument
+.Fa wchan .
+It requires the sleep queue chain associated with
+.Fa wchan
+to have been locked by a prior call to
+.Fn sleepq_lock .
+.Pp
+The
+.Fn sleepq_release
+function unlocks the sleep queue chain associated with
+.Fn wchan
+and is primarily useful when aborting a pending sleep request before one of
+the wait functions is called.
+.Pp
+The
+.Fn sleepq_add
+function places the current thread on the sleep queue associated with the
+wait channel
+.Fa wchan .
+The sleep queue chain associated with argument
+.Fa wchan
+must be locked by a prior call to
+.Fn sleepq_lock
+when this function is called.
+If a lock is specified via the
+.Fa lock
+argument, and if the kernel was compiled with
+.Cd "options INVARIANTS" ,
+then the sleep queue code will perform extra checks to ensure that
+the lock is used by all threads sleeping on
+.Fa wchan .
+The
+.Fa wmesg
+parameter should be a short description of
+.Fa wchan .
+The
+.Fa flags
+parameter is a bitmask consisting of the type of sleep queue being slept on
+and zero or more optional flags.
+The
+.Fa queue
+parameter specifies the sub-queue, in which the contending thread will be
+inserted.
+.Pp
+There are currently three types of sleep queues:
+.Pp
+.Bl -tag -width ".Dv SLEEPQ_CONDVAR" -compact
+.It Dv SLEEPQ_CONDVAR
+A sleep queue used to implement condition variables.
+.It Dv SLEEPQ_SLEEP
+A sleep queue used to implement
+.Xr sleep 9 ,
+.Xr wakeup 9
+and
+.Xr wakeup_one 9 .
+.It Dv SLEEPQ_PAUSE
+A sleep queue used to implement
+.Xr pause 9 .
+.El
+.Pp
+There are currently two optional flag:
+.Pp
+.Bl -tag -width ".Dv SLEEPQ_INTERRUPTIBLE" -compact
+.It Dv SLEEPQ_INTERRUPTIBLE
+The current thread is entering an interruptible sleep.
+.El
+.Bl -tag -width ".Dv SLEEPQ_STOP_ON_BDRY" -compact
+.It Dv SLEEPQ_STOP_ON_BDRY
+When thread is entering an interruptible sleep, do not stop it upon
+arrival of stop action, like
+.Dv SIGSTOP .
+Wake it up instead.
+.El
+.Pp
+A timeout on the sleep may be specified by calling
+.Fn sleepq_set_timeout
+after
+.Fn sleepq_add .
+The
+.Fa wchan
+parameter should be the same value from the preceding call to
+.Fn sleepq_add ,
+and the sleep queue chain associated with
+.Fa wchan
+must have been locked by a prior call to
+.Fn sleepq_lock .
+The
+.Fa timo
+parameter should specify the timeout value in ticks.
+.Pp
+.Fn sleepq_set_timeout_sbt
+function takes
+.Fa sbt
+argument instead of
+.Fa timo .
+It allows to specify relative or absolute wakeup time with higher resolution
+in form of
+.Vt sbintime_t .
+The parameter
+.Fa pr
+allows to specify wanted absolute event precision.
+The parameter
+.Fa flags
+allows to pass additional
+.Fn callout_reset_sbt
+flags.
+.Pp
+The current thread may be marked interruptible by calling
+.Fn sleepq_catch_signals
+with
+.Fa 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
+.Fa wchan
+should have been locked by a prior call to
+.Fn sleepq_lock .
+.Pp
+Once the thread is ready to suspend,
+one of the wait functions is called to put the current thread to sleep
+until it is awakened and to context switch to another thread.
+The
+.Fn sleepq_wait
+function is used for non-interruptible sleeps that do not have a timeout.
+The
+.Fn sleepq_timedwait
+function is used for non-interruptible sleeps that have had a timeout set via
+.Fn sleepq_set_timeout .
+The
+.Fn sleepq_wait_sig
+function is used for interruptible sleeps that do not have a timeout.
+The
+.Fn sleepq_timedwait_sig
+function is used for interruptible sleeps that do have a timeout set.
+The
+.Fa wchan
+argument to all of the wait functions is the wait channel being slept
+on.
+The sleep queue chain associated with argument
+.Fa wchan
+needs to have been locked with a prior call to
+.Fn sleepq_lock .
+The
+.Fa signal_caught
+parameter to
+.Fn sleepq_timedwait_sig
+specifies if a previous call to
+.Fn sleepq_catch_signals
+found a pending signal.
+.Pp
+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
+.Er EWOULDBLOCK
+is returned.
+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
+.Fn sleepq_calc_signal_retval
+should be called to determine if the sleep was interrupted by a signal.
+If so,
+.Fn sleepq_calc_signal_retval
+returns
+.Er ERESTART
+if the interrupting signal is restartable and
+.Er EINTR
+otherwise.
+If the sleep was not interrupted by a signal,
+.Fn sleepq_calc_signal_retval
+will return 0.
+.Pp
+A sleeping thread is normally resumed by the
+.Fn sleepq_broadcast
+and
+.Fn sleepq_signal
+functions.
+The
+.Fn sleepq_signal
+function awakens the highest priority thread sleeping on a wait channel while
+.Fn sleepq_broadcast
+awakens all of the threads sleeping on a wait channel.
+The
+.Fa wchan
+argument specifics which wait channel to awaken.
+The
+.Fa flags
+argument must match the sleep queue type contained in the
+.Fa flags
+argument passed to
+.Fn sleepq_add
+by the threads sleeping on the wait channel.
+If the
+.Fa pri
+argument does not equal \-1,
+then each thread that is awakened will have its priority raised to
+.Fa pri
+if it has a lower priority.
+The sleep queue chain associated with argument
+.Fa wchan
+must be locked by a prior call to
+.Fn sleepq_lock
+before calling any of these functions.
+The
+.Fa queue
+argument specifies the sub-queue, from which threads need to be woken up.
+.Pp
+A thread in an interruptible sleep can be interrupted by another thread via
+the
+.Fn sleepq_abort
+function.
+The
+.Fa td
+argument specifies the thread to interrupt.
+An individual thread can also be awakened from sleeping on a specific wait
+channel via the
+.Fn sleepq_remove
+function.
+The
+.Fa td
+argument specifies the thread to awaken and the
+.Fa wchan
+argument specifies the wait channel to awaken it from.
+If the thread
+.Fa td
+is not blocked on the wait channel
+.Fa 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
+sufficient.
+One possible use is waking up a specific thread from a widely shared sleep
+channel.
+.Pp
+The
+.Fn sleepq_sleepcnt
+function offer a simple way to retrieve the number of threads sleeping for
+the specified
+.Fa queue ,
+given a
+.Fa wchan .
+.Pp
+The
+.Fn sleepq_type
+function returns the type of
+.Fa wchan
+associated to a sleepqueue.
+.Pp
+The
+.Fn sleepq_abort ,
+.Fn sleepq_broadcast ,
+and
+.Fn sleepq_signal
+functions all return a boolean value.
+If the return value is true,
+then at least one thread was resumed that is currently swapped out.
+The caller is responsible for awakening the scheduler process so that the
+resumed thread will be swapped back in.
+This is done by calling the
+.Fn kick_proc0
+function after releasing the sleep queue chain lock via a call to
+.Fn sleepq_release .
+.Pp
+The sleep queue interface is currently used to implement the
+.Xr sleep 9
+and
+.Xr condvar 9
+interfaces.
+Almost all other code in the kernel should use one of those interfaces rather
+than manipulating sleep queues directly.
+.Sh SEE ALSO
+.Xr condvar 9 ,
+.Xr runqueue 9 ,
+.Xr scheduler 9 ,
+.Xr sleep 9 ,
+.Xr timeout 9
OpenPOWER on IntegriCloud