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 December 12, 2009 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_sleepcnt , 45.Nm sleepq_timedwait , 46.Nm sleepq_timedwait_sig , 47.Nm sleepq_wait , 48.Nm sleepq_wait_sig 49.Nd manage the queues of sleeping threads 50.Sh SYNOPSIS 51.In sys/param.h 52.In sys/sleepqueue.h 53.Ft void 54.Fn init_sleepqueues "void" 55.Ft int 56.Fn sleepq_abort "struct thread *td" 57.Ft void 58.Fn sleepq_add "void *wchan" "struct lock_object *lock" "const char *wmesg" "int flags" "int queue" 59.Ft struct sleepqueue * 60.Fn sleepq_alloc "void" 61.Ft int 62.Fn sleepq_broadcast "void *wchan" "int flags" "int pri" "int queue" 63.Ft int 64.Fn sleepq_calc_signal_retval "int sig" 65.Ft int 66.Fn sleepq_catch_signals "void *wchan" 67.Ft void 68.Fn sleepq_free "struct sleepqueue *sq" 69.Ft struct sleepqueue * 70.Fn sleepq_lookup "void *wchan" 71.Ft void 72.Fn sleepq_lock "void *wchan" 73.Ft void 74.Fn sleepq_release "void *wchan" 75.Ft void 76.Fn sleepq_remove "struct thread *td" "void *wchan" 77.Ft int 78.Fn sleepq_signal "void *wchan" "int flags" "int pri" "int queue" 79.Ft void 80.Fn sleepq_set_timeout "void *wchan" "int timo" 81.Ft u_int 82.Fn sleepq_sleepcnt "void *wchan" "int queue" 83.Ft int 84.Fn sleepq_timedwait "void *wchan" 85.Ft int 86.Fn sleepq_timedwait_sig "void *wchan" "int signal_caught" 87.Ft void 88.Fn sleepq_wait "void *wchan" 89.Ft int 90.Fn sleepq_wait_sig "void *wchan" 91.Sh DESCRIPTION 92Sleep queues provide a mechanism for suspending execution of a thread until 93some condition is met. 94Each queue is associated with a specific wait channel when it is active, 95and only one queue may be associated with a wait channel at any given point 96in time. 97The implementation of each wait channel splits its sleepqueue into 2 sub-queues 98in order to enable some optimizations on threads' wakeups. 99An active queue holds a list of threads that are blocked on the associated 100wait channel. 101Threads that are not blocked on a wait channel have an associated inactive 102sleep queue. 103When a thread blocks on a wait channel it donates its inactive sleep queue 104to the wait channel. 105When a thread is resumed, 106the wait channel that it was blocked on gives it an inactive sleep queue for 107later use. 108.Pp 109The 110.Fn sleepq_alloc 111function allocates an inactive sleep queue and is used to assign a 112sleep queue to a thread during thread creation. 113The 114.Fn sleepq_free 115function frees the resources associated with an inactive sleep queue and is 116used to free a queue during thread destruction. 117.Pp 118Active sleep queues are stored in a hash table hashed on the addresses pointed 119to by wait channels. 120Each bucket in the hash table contains a sleep queue chain. 121A sleep queue chain contains a spin mutex and a list of sleep queues that hash 122to that specific chain. 123Active sleep queues are protected by their chain's spin mutex. 124The 125.Fn init_sleepqueues 126function initializes the hash table of sleep queue chains. 127.Pp 128The 129.Fn sleepq_lock 130function locks the sleep queue chain associated with wait channel 131.Fa wchan . 132.Pp 133The 134.Fn sleepq_lookup 135returns a pointer to the currently active sleep queue for that wait 136channel associated with 137.Fa wchan 138or 139.Dv NULL 140if there is no active sleep queue associated with 141argument 142.Fa wchan . 143It requires the sleep queue chain associated with 144.Fa wchan 145to have been locked by a prior call to 146.Fn sleepq_lock . 147.Pp 148The 149.Fn sleepq_release 150function unlocks the sleep queue chain associated with 151.Fn wchan 152and is primarily useful when aborting a pending sleep request before one of 153the wait functions is called. 154.Pp 155The 156.Fn sleepq_add 157function places the current thread on the sleep queue associated with the 158wait channel 159.Fa wchan . 160The sleep queue chain associated with argument 161.Fa wchan 162must be locked by a prior call to 163.Fn sleepq_lock 164when this function is called. 165If a lock is specified via the 166.Fa lock 167argument, and if the kernel was compiled with 168.Cd "options INVARIANTS" , 169then the sleep queue code will perform extra checks to ensure that 170the lock is used by all threads sleeping on 171.Fa wchan . 172The 173.Fa wmesg 174parameter should be a short description of 175.Fa wchan . 176The 177.Fa flags 178parameter is a bitmask consisting of the type of sleep queue being slept on 179and zero or more optional flags. 180The 181.Fa queue 182parameter specifies the sub-queue, in which the contending thread will be 183inserted. 184.Pp 185There are currently three types of sleep queues: 186.Pp 187.Bl -tag -width ".Dv SLEEPQ_CONDVAR" -compact 188.It Dv SLEEPQ_CONDVAR 189A sleep queue used to implement condition variables. 190.It Dv SLEEPQ_SLEEP 191A sleep queue used to implement 192.Xr sleep 9 , 193.Xr wakeup 9 194and 195.Xr wakeup_one 9 . 196.It Dv SLEEPQ_PAUSE 197A sleep queue used to implement 198.Xr pause 9 . 199.El 200.Pp 201There are currently two optional flag: 202.Pp 203.Bl -tag -width ".Dv SLEEPQ_INTERRUPTIBLE" -compact 204.It Dv SLEEPQ_INTERRUPTIBLE 205The current thread is entering an interruptible sleep. 206.El 207.Bl -tag -width ".Dv SLEEPQ_STOP_ON_BDRY" -compact 208.It Dv SLEEPQ_STOP_ON_BDRY 209When thread is entering an interruptible sleep, do not stop it upon 210arrival of stop action, like 211.Dv SIGSTOP . 212Wake it up instead. 213.El 214.Pp 215A timeout on the sleep may be specified by calling 216.Fn sleepq_set_timeout 217after 218.Fn sleepq_add . 219The 220.Fa wchan 221parameter should be the same value from the preceding call to 222.Fn sleepq_add , 223and the sleep queue chain associated with 224.Fa wchan 225must have been locked by a prior call to 226.Fn sleepq_lock . 227The 228.Fa timo 229parameter should specify the timeout value in ticks. 230.Pp 231The current thread may be marked interruptible by calling 232.Fn sleepq_catch_signals 233with 234.Fa wchan 235set to the wait channel. 236This function returns a signal number if there are any pending signals for 237the current thread and 0 if there is not a pending signal. 238The sleep queue chain associated with argument 239.Fa wchan 240should have been locked by a prior call to 241.Fn sleepq_lock . 242.Pp 243Once the thread is ready to suspend, 244one of the wait functions is called to put the current thread to sleep 245until it is awakened and to context switch to another thread. 246The 247.Fn sleepq_wait 248function is used for non-interruptible sleeps that do not have a timeout. 249The 250.Fn sleepq_timedwait 251function is used for non-interruptible sleeps that have had a timeout set via 252.Fn sleepq_set_timeout . 253The 254.Fn sleepq_wait_sig 255function is used for interruptible sleeps that do not have a timeout. 256The 257.Fn sleepq_timedwait_sig 258function is used for interruptible sleeps that do have a timeout set. 259The 260.Fa wchan 261argument to all of the wait functions is the wait channel being slept 262on. 263The sleep queue chain associated with argument 264.Fa wchan 265needs to have been locked with a prior call to 266.Fn sleepq_lock . 267The 268.Fa signal_caught 269parameter to 270.Fn sleepq_timedwait_sig 271specifies if a previous call to 272.Fn sleepq_catch_signals 273found a pending signal. 274.Pp 275When the thread is resumed, 276the wait functions return a non-zero value if the thread was awakened due to 277an interrupt other than a signal or a timeout. 278If the sleep timed out, then 279.Er EWOULDBLOCK 280is returned. 281If the sleep was interrupted by something other than a signal, 282then some other return value will be returned. 283If zero is returned after resuming from an interruptible sleep, 284then 285.Fn sleepq_calc_signal_retval 286should be called to determine if the sleep was interrupted by a signal. 287If so, 288.Fn sleepq_calc_signal_retval 289returns 290.Er ERESTART 291if the interrupting signal is restartable and 292.Er EINTR 293otherwise. 294If the sleep was not interrupted by a signal, 295.Fn sleepq_calc_signal_retval 296will return 0. 297.Pp 298A sleeping thread is normally resumed by the 299.Fn sleepq_broadcast 300and 301.Fn sleepq_signal 302functions. 303The 304.Fn sleepq_signal 305function awakens the highest priority thread sleeping on a wait channel while 306.Fn sleepq_broadcast 307awakens all of the threads sleeping on a wait channel. 308The 309.Fa wchan 310argument specifics which wait channel to awaken. 311The 312.Fa flags 313argument must match the sleep queue type contained in the 314.Fa flags 315argument passed to 316.Fn sleepq_add 317by the threads sleeping on the wait channel. 318If the 319.Fa pri 320argument does not equal \-1, 321then each thread that is awakened will have its priority raised to 322.Fa pri 323if it has a lower priority. 324The sleep queue chain associated with argument 325.Fa wchan 326must be locked by a prior call to 327.Fn sleepq_lock 328before calling any of these functions. 329The 330.Fa queue 331argument specifies the sub-queue, from which threads need to be woken up. 332.Pp 333A thread in an interruptible sleep can be interrupted by another thread via 334the 335.Fn sleepq_abort 336function. 337The 338.Fa td 339argument specifies the thread to interrupt. 340An individual thread can also be awakened from sleeping on a specific wait 341channel via the 342.Fn sleepq_remove 343function. 344The 345.Fa td 346argument specifies the thread to awaken and the 347.Fa wchan 348argument specifies the wait channel to awaken it from. 349If the thread 350.Fa td 351is not blocked on the the wait channel 352.Fa wchan 353then this function will not do anything, 354even if the thread is asleep on a different wait channel. 355This function should only be used if one of the other functions above is not 356sufficient. 357One possible use is waking up a specific thread from a widely shared sleep 358channel. 359.Pp 360The 361.Fn sleepq_sleepcnt 362function offer a simple way to retrieve the number of threads sleeping for 363the specified 364.Fa queue , 365given a 366.Fa wchan . 367.Pp 368The 369.Fn sleepq_abort , 370.Fn sleepq_broadcast , 371and 372.Fn sleepq_signal 373functions all return a boolean value. 374If the return value is true, 375then at least one thread was resumed that is currently swapped out. 376The caller is responsible for awakening the scheduler process so that the 377resumed thread will be swapped back in. 378This is done by calling the 379.Fn kick_proc0 380function after releasing the sleep queue chain lock via a call to 381.Fn sleepq_release . 382.Pp 383The sleep queue interface is currently used to implement the 384.Xr sleep 9 385and 386.Xr condvar 9 387interfaces. 388Almost all other code in the kernel should use one of those interfaces rather 389than manipulating sleep queues directly. 390.Sh SEE ALSO 391.Xr condvar 9 , 392.Xr runqueue 9 , 393.Xr scheduler 9 , 394.Xr sleep 9 395