1.\" Copyright (c) 2000-2004 John H. Baldwin <jhb@FreeBSD.org> 2.\" 3.\" Redistribution and use in source and binary forms, with or without 4.\" modification, are permitted provided that the following conditions 5.\" are met: 6.\" 1. Redistributions of source code must retain the above copyright 7.\" notice, this list of conditions and the following disclaimer. 8.\" 2. Redistributions in binary form must reproduce the above copyright 9.\" notice, this list of conditions and the following disclaimer in the 10.\" documentation and/or other materials provided with the distribution. 11.\" 12.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR 13.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 14.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 15.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT, 16.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 17.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 18.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 19.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 20.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 21.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 22.\" 23.\" $FreeBSD$ 24.\" 25.Dd June 19, 2019 26.Dt SLEEPQUEUE 9 27.Os 28.Sh NAME 29.Nm init_sleepqueues , 30.Nm sleepq_abort , 31.Nm sleepq_add , 32.Nm sleepq_alloc , 33.Nm sleepq_broadcast , 34.Nm sleepq_free , 35.Nm sleepq_lock , 36.Nm sleepq_lookup , 37.Nm sleepq_release , 38.Nm sleepq_remove , 39.Nm sleepq_signal , 40.Nm sleepq_set_timeout , 41.Nm sleepq_set_timeout_sbt , 42.Nm sleepq_sleepcnt , 43.Nm sleepq_timedwait , 44.Nm sleepq_timedwait_sig , 45.Nm sleepq_type , 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 int 55.Fn sleepq_abort "struct thread *td" 56.Ft void 57.Fn sleepq_add "const void *wchan" "struct lock_object *lock" "const char *wmesg" "int flags" "int queue" 58.Ft struct sleepqueue * 59.Fn sleepq_alloc "void" 60.Ft int 61.Fn sleepq_broadcast "const void *wchan" "int flags" "int pri" "int queue" 62.Ft void 63.Fn sleepq_free "struct sleepqueue *sq" 64.Ft struct sleepqueue * 65.Fn sleepq_lookup "const void *wchan" 66.Ft void 67.Fn sleepq_lock "const void *wchan" 68.Ft void 69.Fn sleepq_release "const void *wchan" 70.Ft void 71.Fn sleepq_remove "struct thread *td" "const void *wchan" 72.Ft int 73.Fn sleepq_signal "const void *wchan" "int flags" "int pri" "int queue" 74.Ft void 75.Fn sleepq_set_timeout "const void *wchan" "int timo" 76.Ft void 77.Fn sleepq_set_timeout_sbt "const void *wchan" "sbintime_t sbt" \ 78"sbintime_t pr" "int flags" 79.Ft u_int 80.Fn sleepq_sleepcnt "const void *wchan" "int queue" 81.Ft int 82.Fn sleepq_timedwait "const void *wchan" "int pri" 83.Ft int 84.Fn sleepq_timedwait_sig "const void *wchan" "int pri" 85.Ft int 86.Fn sleepq_type "const void *wchan" 87.Ft void 88.Fn sleepq_wait "const void *wchan" "int pri" 89.Ft int 90.Fn sleepq_wait_sig "const void *wchan" "int pri" 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 231.Fn sleepq_set_timeout_sbt 232function takes 233.Fa sbt 234argument instead of 235.Fa timo . 236It allows to specify relative or absolute wakeup time with higher resolution 237in form of 238.Vt sbintime_t . 239The parameter 240.Fa pr 241allows to specify wanted absolute event precision. 242The parameter 243.Fa flags 244allows to pass additional 245.Fn callout_reset_sbt 246flags. 247.Pp 248Once the thread is ready to suspend, 249one of the wait functions is called to put the current thread to sleep 250until it is awakened and to context switch to another thread. 251The 252.Fn sleepq_wait 253function is used for non-interruptible sleeps that do not have a timeout. 254The 255.Fn sleepq_timedwait 256function is used for non-interruptible sleeps that have had a timeout set via 257.Fn sleepq_set_timeout . 258The 259.Fn sleepq_wait_sig 260function is used for interruptible sleeps that do not have a timeout. 261The 262.Fn sleepq_timedwait_sig 263function is used for interruptible sleeps that do have a timeout set. 264The 265.Fa wchan 266argument to all of the wait functions is the wait channel being slept 267on. 268The sleep queue chain associated with argument 269.Fa wchan 270needs to have been locked with a prior call to 271.Fn sleepq_lock . 272The 273.Fa pri 274argument is used to set the priority of the thread when it is awakened. 275If it is set to zero, the thread's priority is left alone. 276.Pp 277When the thread is resumed, 278the wait functions return a non-zero value if the thread was awakened due to 279an interrupt other than a signal or a timeout. 280If the sleep timed out, then 281.Er EWOULDBLOCK 282is returned. 283If the sleep was interrupted by something other than a signal, 284then some other return value will be returned. 285.Pp 286A sleeping thread is normally resumed by the 287.Fn sleepq_broadcast 288and 289.Fn sleepq_signal 290functions. 291The 292.Fn sleepq_signal 293function awakens the highest priority thread sleeping on a wait channel 294(if SLEEPQ_UNFAIR flag is set, thread that went to sleep recently) while 295.Fn sleepq_broadcast 296awakens all of the threads sleeping on a wait channel. 297The 298.Fa wchan 299argument specifics which wait channel to awaken. 300The 301.Fa flags 302argument must match the sleep queue type contained in the 303.Fa flags 304argument passed to 305.Fn sleepq_add 306by the threads sleeping on the wait channel. 307If the 308.Fa pri 309argument does not equal \-1, 310then each thread that is awakened will have its priority raised to 311.Fa pri 312if it has a lower priority. 313The sleep queue chain associated with argument 314.Fa wchan 315must be locked by a prior call to 316.Fn sleepq_lock 317before calling any of these functions. 318The 319.Fa queue 320argument specifies the sub-queue, from which threads need to be woken up. 321.Pp 322A thread in an interruptible sleep can be interrupted by another thread via 323the 324.Fn sleepq_abort 325function. 326The 327.Fa td 328argument specifies the thread to interrupt. 329An individual thread can also be awakened from sleeping on a specific wait 330channel via the 331.Fn sleepq_remove 332function. 333The 334.Fa td 335argument specifies the thread to awaken and the 336.Fa wchan 337argument specifies the wait channel to awaken it from. 338If the thread 339.Fa td 340is not blocked on the wait channel 341.Fa wchan 342then this function will not do anything, 343even if the thread is asleep on a different wait channel. 344This function should only be used if one of the other functions above is not 345sufficient. 346One possible use is waking up a specific thread from a widely shared sleep 347channel. 348.Pp 349The 350.Fn sleepq_sleepcnt 351function offer a simple way to retrieve the number of threads sleeping for 352the specified 353.Fa queue , 354given a 355.Fa wchan . 356.Pp 357The 358.Fn sleepq_type 359function returns the type of 360.Fa wchan 361associated to a sleepqueue. 362.Pp 363The 364.Fn sleepq_abort , 365.Fn sleepq_broadcast , 366and 367.Fn sleepq_signal 368functions all return a boolean value. 369If the return value is true, 370then at least one thread was resumed that is currently swapped out. 371The caller is responsible for awakening the scheduler process so that the 372resumed thread will be swapped back in. 373This is done by calling the 374.Fn kick_proc0 375function after releasing the sleep queue chain lock via a call to 376.Fn sleepq_release . 377.Pp 378The sleep queue interface is currently used to implement the 379.Xr sleep 9 380and 381.Xr condvar 9 382interfaces. 383Almost all other code in the kernel should use one of those interfaces rather 384than manipulating sleep queues directly. 385.Sh SEE ALSO 386.Xr callout 9 , 387.Xr condvar 9 , 388.Xr runqueue 9 , 389.Xr scheduler 9 , 390.Xr sleep 9 391