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 two 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_MSLEEP 182A sleep queue used to implement 183.Xr msleep 9 , 184.Xr wakeup 9 185and 186.Xr wakeup_one 9 . 187.El 188.Pp 189There is currently only one optional flag: 190.Pp 191.Bl -tag -width ".Dv SLEEPQ_INTERRUPTIBLE" -compact 192.It Dv SLEEPQ_INTERRUPTIBLE 193The current thread is entering an interruptible sleep. 194.El 195.Pp 196A timeout on the sleep may be specified by calling 197.Fn sleepq_set_timeout 198after 199.Fn sleepq_add . 200The 201.Fa wchan 202parameter should be the same value from the preceding call to 203.Fn sleepq_add , 204and the sleep queue chain associated with 205.Fa wchan 206must have been locked by a prior call to 207.Fn sleepq_lock . 208The 209.Fa timo 210parameter should specify the timeout value in ticks. 211.Pp 212The current thread may be marked interruptible by calling 213.Fn sleepq_catch_signals 214with 215.Fa wchan 216set to the wait channel. 217This function returns a signal number if there are any pending signals for 218the current thread and 0 if there is not a pending signal. 219The sleep queue chain associated with argument 220.Fa wchan 221should have been locked by a prior call to 222.Fn sleepq_lock . 223.Pp 224Once the thread is ready to suspend, 225one of the wait functions is called to put the current thread to sleep 226until it is awakened and to context switch to another thread. 227The 228.Fn sleepq_wait 229function is used for non-interruptible sleeps that do not have a timeout. 230The 231.Fn sleepq_timedwait 232function is used for non-interruptible sleeps that have had a timeout set via 233.Fn sleepq_set_timeout . 234The 235.Fn sleepq_wait_sig 236function is used for interruptible sleeps that do not have a timeout. 237The 238.Fn sleepq_timedwait_sig 239function is used for interruptible sleeps that do have a timeout set. 240The 241.Fa wchan 242argument to all of the wait functions is the wait channel being slept 243on. 244The sleep queue chain associated with argument 245.Fa wchan 246needs to have been locked with a prior call to 247.Fn sleepq_lock . 248The 249.Fa signal_caught 250parameter to 251.Fn sleepq_timedwait_sig 252specifies if a previous call to 253.Fn sleepq_catch_signals 254found a pending signal. 255.Pp 256When the thread is resumed, 257the wait functions return a non-zero value if the thread was awakened due to 258an interrupt other than a signal or a timeout. 259If the sleep timed out, then 260.Er EWOULDBLOCK 261is returned. 262If the sleep was interrupted by something other than a signal, 263then some other return value will be returned. 264If zero is returned after resuming from an interruptible sleep, 265then 266.Fn sleepq_calc_signal_retval 267should be called to determine if the sleep was interrupted by a signal. 268If so, 269.Fn sleepq_calc_signal_retval 270returns 271.Er ERESTART 272if the interrupting signal is restartable and 273.Er EINTR 274otherwise. 275If the sleep was not interrupted by a signal, 276.Fn sleepq_calc_signal_retval 277will return 0. 278.Pp 279A sleeping thread is normally resumed by the 280.Fn sleepq_broadcast 281and 282.Fn sleepq_signal 283functions. 284The 285.Fn sleepq_signal 286function awakens the highest priority thread sleeping on a wait channel while 287.Fn sleepq_broadcast 288awakens all of the threads sleeping on a wait channel. 289The 290.Fa wchan 291argument specifics which wait channel to awaken. 292The 293.Fa flags 294argument must match the sleep queue type contained in the 295.Fa flags 296argument passed to 297.Fn sleepq_add 298by the threads sleeping on the wait channel. 299If the 300.Fa pri 301argument does not equal \-1, 302then each thread that is awakened will have its priority raised to 303.Fa pri 304if it has a lower priority. 305The sleep queue chain associated with argument 306.Fa wchan 307must be locked by a prior call to 308.Fn sleepq_lock 309before calling any of these functions. 310.Pp 311A thread in an interruptible sleep can be interrupted by another thread via 312the 313.Fn sleepq_abort 314function. 315The 316.Fa td 317argument specifies the thread to interrupt. 318An individual thread can also be awakened from sleeping on a specific wait 319channel via the 320.Fn sleepq_remove 321function. 322The 323.Fa td 324argument specifies the thread to awaken and the 325.Fa wchan 326argument specifies the wait channel to awaken it from. 327If the thread 328.Fa td 329is not blocked on the the wait channel 330.Fa wchan 331then this function will not do anything, 332even if the thread is asleep on a different wait channel. 333This function should only be used if one of the other functions above is not 334sufficient. 335One possible use is waking up a specific thread from a widely shared sleep 336channel. 337.Pp 338The sleep queue interface is currently used to implement the 339.Xr msleep 9 340and 341.Xr condvar 9 342interfaces. 343Almost all other code in the kernel should use one of those interfaces rather 344than manipulating sleep queues directly. 345.Sh SEE ALSO 346.Xr condvar 9 , 347.Xr msleep 9 , 348.Xr runqueue 9 , 349.Xr scheduler 9 350