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