diff --git a/en_US.ISO8859-1/books/arch-handbook/smp/chapter.sgml b/en_US.ISO8859-1/books/arch-handbook/smp/chapter.sgml
index 9cee9397d5..bad8690268 100644
--- a/en_US.ISO8859-1/books/arch-handbook/smp/chapter.sgml
+++ b/en_US.ISO8859-1/books/arch-handbook/smp/chapter.sgml
@@ -794,13 +794,154 @@
Sleep Queues
- - Lookup/release
+ A sleep queue is a structure that holds the list of
+ threads asleep on a wait channel. Each thread that is not
+ asleep on a wait channel carries a sleep queue structure
+ around with it. When a thread blocks on a wait channel, it
+ donates its sleep queue structure to that wait channel. Sleep
+ queues associated with a wait channel are stored in a hash
+ table.
- - Adding & waiting.
+ The sleep queue hash table holds sleep queues for wait
+ channels that have at least one blocked thread. Each entry in
+ the hash table is called a sleepqueue chain. The chain
+ contains a linked list of sleep queues and a spin mutex. The
+ spin mutex protects the list of sleep queues as well as the
+ contents of the sleep queue structures on the list. Only one
+ sleep queue is associated with a given wait channel. If
+ multiple threads block on a wait channel than the sleep queues
+ associated with all but the first thread are stored on a list
+ of free sleep queues in the master sleep queue. When a thread
+ is removed from the sleep queue it is given one of the sleep
+ queue structures from the master queue's free list if it is
+ not the only thread asleep on the queue. The last thread is
+ given the master sleep queue when it is resumed. Since
+ threads may be removed from the sleep queue in a different
+ order than they are added, a thread may depart from a sleep
+ queue with a different sleep queue structure than the one it
+ arrived with.
- - Timeout and signal catching.
+ The sleepq_lock function locks the
+ spin mutex of the sleep queue chain that maps to a specific
+ wait channel. The sleepq_lookup function
+ looks in the hash table for the master sleep queue associated
+ with a given wait channel. If no master sleep queue is found,
+ it returns NULL. The sleepq_release
+ function unlocks the spin mutex associated with a given wait
+ channel.
- - Aborting a sleep.
+ A thread is added to a sleep queue via the
+ sleepq_add. This function accepts the
+ wait channel, a pointer to the mutex that protects the wait
+ channel, a wait message description string, and a mask of
+ flags. The sleep queue chain should be locked via
+ sleepq_lock before this function is
+ called. If no mutex protects the wait channel (or it is
+ protected by Giant), then the mutex pointer argument should be
+ NULL. The flags argument contains a type field that indicates
+ the kind of sleep queue that the thread is being added to and
+ a flag to indicate if the sleep is interruptible
+ (SLEEPQ_INTERRUPTIBLE). Currently there are only two types of
+ sleep queues: traditional sleep queues managed via the
+ msleep and wakeup
+ functions (SLEEPQ_MSLEEP) and condition variable sleep queues
+ (SLEEPQ_CONDVAR). The sleep queue type and lock pointer
+ argument are used solely for internal assertion checking. Code
+ that calls sleepq_add should explicitly
+ unlock any interlock protecting the wait channel after the
+ associated sleepqueue chain has been locked via
+ sleepq_lock and before blocking on the
+ sleep queue via one of the waiting functions.
+
+ A timeout for a sleep is set by invoking
+ sleepq_set_timeout. The function accepts
+ the wait channel and the timeout time as a relative tick count
+ as its arguments. If a sleep should be interrupted by
+ arriving signals, the
+ sleepq_catch_signals function should be
+ called as well. This function accepts the wait channel as its
+ only parameter. If there is already a signal pending for this
+ thread, then sleepq_catch_signals will
+ return a signal number; otherwise, it will return 0.
+
+ Once a thread has been added to a sleep queue, it blocks
+ using one of the sleepq_wait functions.
+ There are four wait functions depending on whether or not the
+ caller wishes to use a timeout or have the sleep aborted by
+ caught signals or an interrupt from the userland thread
+ scheduler. The sleepq_wait function
+ simply waits until the current thread is explicitly resumed by
+ one of the wakeup functions. The
+ sleepq_timedwait function waits until
+ either the thread is explicitly resumed or the timeout set by
+ an earlier call to sleepq_set_timeout
+ expires. The sleepq_wait_sig function
+ waits until either the thread is explicitly resumed or its
+ sleep is aborted. The
+ sleepq_timedwait_sig function waits until
+ either the thread is explicitly resumed, the timeout set by an
+ earlier call to sleepq_set_timeout
+ expires, or the thread's sleep is aborted. All of the wait
+ functions accept the wait channel as their first parameter.
+ In addition, the sleepq_timedwait_sig
+ function accepts a second boolean parameter to indicate if the
+ earlier call to sleepq_catch_signals
+ found a pending signal.
+
+ If the thread is explicitly resumed or is aborted by a
+ signal, then a value of zero is returned by the wait function
+ to indicate a successful sleep. If the thread is resumed by
+ either a timeout or an interrupt from the userland thread
+ scheduler then an appropriate errno value is returned instead.
+ Note that since sleepq_wait can only
+ return 0 it does not return anything and the caller should
+ assume a successful sleep. Also, if a thread's sleep times
+ out and is aborted simultaneously then
+ sleepq_timedwait_sig will return an error
+ indicating that a timeout occurred. If an error value of
+ 0 is returned and either sleepq_wait_sig
+ or sleepq_timedwait_sig was used to
+ block, then the function
+ sleepq_calc_signal_retval should be
+ called to check for any pending signals and calculate an
+ appropriate return value if any are found. The signal number
+ returned by the earlier call to
+ sleepq_catch_signals should be passed as
+ the sole argument to
+ sleepq_calc_signal_retval.
+
+ Threads asleep on a wait channel are explicitly resumed by
+ the sleepq_broadcast and
+ sleepq_signal functions. Both functions
+ accept the wait channel from which to resume threads, a
+ priority to raise resumed threads to, and a flags argument to
+ indicate which type of sleep queue is being resumed. The
+ priority argument is treated as a minimum priority. If a
+ thread being resumed already has a higher priority
+ (numerically lower) than the priority argument then its
+ priority is not adjusted. The flags argument is used for
+ internal assertions to ensure that sleep queues are not being
+ treated as the wrong type. For example, the condition
+ variable functions should not resume threads on a traditional
+ sleep queue. The sleepq_broadcast
+ function resumes all threads that are blocked on the specified
+ wait channel while sleepq_signal only
+ resumes the highest priority thread blocked on the wait
+ channel. The sleep queue chain should first be locked via the
+ sleepq_lock function before calling these
+ functions.
+
+ A sleeping thread may have its sleep interrupted by
+ calling the sleepq_abort function. This
+ function must be called with sched_lock
+ held and the thread must be queued on a sleep queue. A thread
+ may also be removed from a specific sleep queue via the
+ sleepq_remove function. This function
+ accepts both a thread and a wait channel as an argument and
+ only awakens the thread if it is on the sleep queue for the
+ specified wait channel. If the thread is not on a sleep queue
+ or it is on a sleep queue for a different wait channel, then
+ this function does nothing.
@@ -998,5 +1139,12 @@
locks and hold a single execution context.
+
+
+ wait channel
+
+ A kernel virtual address that threads may sleep on.
+
+