1.\" Copyright (c) 2000-2004 John H. Baldwin <jhb@FreeBSD.org> 2.\" All rights reserved. 3.\" 4.\" Redistribution and use in source and binary forms, with or without 5.\" modification, are permitted provided that the following conditions 6.\" are met: 7.\" 1. Redistributions of source code must retain the above copyright 8.\" notice, this list of conditions and the following disclaimer. 9.\" 2. Redistributions in binary form must reproduce the above copyright 10.\" notice, this list of conditions and the following disclaimer in the 11.\" documentation and/or other materials provided with the distribution. 12.\" 13.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR 14.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 15.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 16.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT, 17.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 18.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 19.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 20.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 22.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23.\" 24.\" $FreeBSD$ 25.\" 26.Dd March 10, 2004 27.Dt SLEEPQUEUE 9 28.Os 29.Sh NAME 30.Nm init_sleepqueues , 31.Nm sleepq_abort , 32.Nm sleepq_add , 33.Nm sleepq_alloc , 34.Nm sleepq_broadcast , 35.Nm sleepq_calc_signal_retval , 36.Nm sleepq_catch_signals , 37.Nm sleepq_free , 38.Nm sleepq_lock , 39.Nm sleepq_lookup , 40.Nm sleepq_release , 41.Nm sleepq_remove , 42.Nm sleepq_signal , 43.Nm sleepq_set_timeout , 44.Nm sleepq_timedwait , 45.Nm sleepq_timedwait_sig , 46.Nm sleepq_wait , 47.Nm sleepq_wait_sig 48.Nd manage the queues of sleeping threads 49.Sh SYNOPSIS 50.In sys/param.h 51.In sys/sleepqueue.h 52.Ft void 53.Fn init_sleepqueues "void" 54.Ft void 55.Fn sleepq_abort "struct thread *td" 56.Ft void 57.Fn sleepq_add "void *wchan" "struct lock_object *lock" "const char *wmesg" "int flags" 58.Ft struct sleepqueue * 59.Fn sleepq_alloc "void" 60.Ft void 61.Fn sleepq_broadcast "void *wchan" "int flags" "int pri" 62.Ft int 63.Fn sleepq_calc_signal_retval "int sig" 64.Ft int 65.Fn sleepq_catch_signals "void *wchan" 66.Ft void 67.Fn sleepq_free "struct sleepqueue *sq" 68.Ft struct sleepqueue * 69.Fn sleepq_lookup "void *wchan" 70.Ft void 71.Fn sleepq_lock "void *wchan" 72.Ft void 73.Fn sleepq_release "void *wchan" 74.Ft void 75.Fn sleepq_remove "struct thread *td" "void *wchan" 76.Ft void 77.Fn sleepq_signal "void *wchan" "int flags" "int pri" 78.Ft void 79.Fn sleepq_set_timeout "void *wchan" "int timo" 80.Ft int 81.Fn sleepq_timedwait "void *wchan" 82.Ft int 83.Fn sleepq_timedwait_sig "void *wchan" "int signal_caught" 84.Ft void 85.Fn sleepq_wait "void *wchan" 86.Ft int 87.Fn sleepq_wait_sig "void *wchan" 88.Sh DESCRIPTION 89Sleep queues provide a mechanism for suspending execution of a thread until 90some condition is met. 91Each queue is associated with a specific wait channel when it is active, 92and only one queue may be associated with a wait channel at any given point 93in time. 94An active queue holds a list of threads that are blocked on the associated 95wait channel. 96Threads that are not blocked on a wait channel have an associated inactive 97sleep queue. 98When a thread blocks on a wait channel it donates its inactive sleep queue 99to the wait channel. 100When a thread is resumed, 101the wait channel that it was blocked on gives it an inactive sleep queue for 102later use. 103.Pp 104The 105.Fn sleepq_alloc 106function allocates an inactive sleep queue and is used to assign a 107sleep queue to a thread during thread creation. 108The 109.Fn sleepq_free 110function frees the resources associated with an inactive sleep queue and is 111used to free a queue during thread destruction. 112.Pp 113Active sleep queues are stored in a hash table hashed on the addresses pointed 114to by wait channels. 115Each bucket in the hash table contains a sleep queue chain. 116A sleep queue chain contains a spin mutex and a list of sleep queues that hash 117to that specific chain. 118Active sleep queues are protected by their chain's spin mutex. 119The 120.Fn init_sleepqueues 121function initializes the hash table of sleep queue chains. 122.Pp 123The 124.Fn sleepq_lock 125function locks the sleep queue chain associated with wait channel 126.Fa wchan . 127.Pp 128The 129.Fn sleepq_lookup 130returns a pointer to the currently active sleep queue for that wait 131channel associated with 132.Fa wchan 133or 134.Dv NULL 135if there is no active sleep queue associated with 136argument 137.Fa wchan . 138It requires the sleep queue chain associated with 139.Fa wchan 140to have been locked by a prior call to 141.Fn sleepq_lock . 142.Pp 143The 144.Fn sleepq_release 145function unlocks the sleep queue chain associated with 146.Fn wchan 147and is primarily useful when aborting a pending sleep request before one of 148the wait functions is called. 149.Pp 150The 151.Fn sleepq_add 152function places the current thread on the sleep queue associated with the 153wait channel 154.Fa wchan . 155The sleep queue chain associated with argument 156.Fa wchan 157must be locked by a prior call to 158.Fn sleepq_lock 159when this function is called. 160If a lock is specified via the 161.Fa lock 162argument, and if the kernel was compiled with 163.Cd "options INVARIANTS" , 164then the sleep queue code will perform extra checks to ensure that 165the lock is used by all threads sleeping on 166.Fa wchan . 167The 168.Fa wmesg 169parameter should be a short description of 170.Fa wchan . 171The 172.Fa flags 173parameter is a bitmask consisting of the type of sleep queue being slept on 174and zero or more optional flags. 175.Pp 176There are currently three types of sleep queues: 177.Pp 178.Bl -tag -width ".Dv SLEEPQ_CONDVAR" -compact 179.It Dv SLEEPQ_CONDVAR 180A sleep queue used to implement condition variables. 181.It Dv SLEEPQ_SLEEP 182A sleep queue used to implement 183.Xr sleep 9 , 184.Xr wakeup 9 185and 186.Xr wakeup_one 9 . 187.It Dv SLEEPQ_PAUSE 188A sleep queue used to implement 189.Xr pause 9 . 190.El 191.Pp 192There is currently only one optional flag: 193.Pp 194.Bl -tag -width ".Dv SLEEPQ_INTERRUPTIBLE" -compact 195.It Dv SLEEPQ_INTERRUPTIBLE 196The current thread is entering an interruptible sleep. 197.El 198.Pp 199A timeout on the sleep may be specified by calling 200.Fn sleepq_set_timeout 201after 202.Fn sleepq_add . 203The 204.Fa wchan 205parameter should be the same value from the preceding call to 206.Fn sleepq_add , 207and the sleep queue chain associated with 208.Fa wchan 209must have been locked by a prior call to 210.Fn sleepq_lock . 211The 212.Fa timo 213parameter should specify the timeout value in ticks. 214.Pp 215The current thread may be marked interruptible by calling 216.Fn sleepq_catch_signals 217with 218.Fa wchan 219set to the wait channel. 220This function returns a signal number if there are any pending signals for 221the current thread and 0 if there is not a pending signal. 222The sleep queue chain associated with argument 223.Fa wchan 224should have been locked by a prior call to 225.Fn sleepq_lock . 226.Pp 227Once the thread is ready to suspend, 228one of the wait functions is called to put the current thread to sleep 229until it is awakened and to context switch to another thread. 230The 231.Fn sleepq_wait 232function is used for non-interruptible sleeps that do not have a timeout. 233The 234.Fn sleepq_timedwait 235function is used for non-interruptible sleeps that have had a timeout set via 236.Fn sleepq_set_timeout . 237The 238.Fn sleepq_wait_sig 239function is used for interruptible sleeps that do not have a timeout. 240The 241.Fn sleepq_timedwait_sig 242function is used for interruptible sleeps that do have a timeout set. 243The 244.Fa wchan 245argument to all of the wait functions is the wait channel being slept 246on. 247The sleep queue chain associated with argument 248.Fa wchan 249needs to have been locked with a prior call to 250.Fn sleepq_lock . 251The 252.Fa signal_caught 253parameter to 254.Fn sleepq_timedwait_sig 255specifies if a previous call to 256.Fn sleepq_catch_signals 257found a pending signal. 258.Pp 259When the thread is resumed, 260the wait functions return a non-zero value if the thread was awakened due to 261an interrupt other than a signal or a timeout. 262If the sleep timed out, then 263.Er EWOULDBLOCK 264is returned. 265If the sleep was interrupted by something other than a signal, 266then some other return value will be returned. 267If zero is returned after resuming from an interruptible sleep, 268then 269.Fn sleepq_calc_signal_retval 270should be called to determine if the sleep was interrupted by a signal. 271If so, 272.Fn sleepq_calc_signal_retval 273returns 274.Er ERESTART 275if the interrupting signal is restartable and 276.Er EINTR 277otherwise. 278If the sleep was not interrupted by a signal, 279.Fn sleepq_calc_signal_retval 280will return 0. 281.Pp 282A sleeping thread is normally resumed by the 283.Fn sleepq_broadcast 284and 285.Fn sleepq_signal 286functions. 287The 288.Fn sleepq_signal 289function awakens the highest priority thread sleeping on a wait channel while 290.Fn sleepq_broadcast 291awakens all of the threads sleeping on a wait channel. 292The 293.Fa wchan 294argument specifics which wait channel to awaken. 295The 296.Fa flags 297argument must match the sleep queue type contained in the 298.Fa flags 299argument passed to 300.Fn sleepq_add 301by the threads sleeping on the wait channel. 302If the 303.Fa pri 304argument does not equal \-1, 305then each thread that is awakened will have its priority raised to 306.Fa pri 307if it has a lower priority. 308The sleep queue chain associated with argument 309.Fa wchan 310must be locked by a prior call to 311.Fn sleepq_lock 312before calling any of these functions. 313.Pp 314A thread in an interruptible sleep can be interrupted by another thread via 315the 316.Fn sleepq_abort 317function. 318The 319.Fa td 320argument specifies the thread to interrupt. 321An individual thread can also be awakened from sleeping on a specific wait 322channel via the 323.Fn sleepq_remove 324function. 325The 326.Fa td 327argument specifies the thread to awaken and the 328.Fa wchan 329argument specifies the wait channel to awaken it from. 330If the thread 331.Fa td 332is not blocked on the the wait channel 333.Fa wchan 334then this function will not do anything, 335even if the thread is asleep on a different wait channel. 336This function should only be used if one of the other functions above is not 337sufficient. 338One possible use is waking up a specific thread from a widely shared sleep 339channel. 340.Pp 341The sleep queue interface is currently used to implement the 342.Xr sleep 9 343and 344.Xr condvar 9 345interfaces. 346Almost all other code in the kernel should use one of those interfaces rather 347than manipulating sleep queues directly. 348.Sh SEE ALSO 349.Xr condvar 9 , 350.Xr runqueue 9 , 351.Xr scheduler 9 , 352.Xr sleep 9 353