xref: /freebsd/share/man/man9/sleepqueue.9 (revision 608da65de9552d5678c1000776ed69da04a45983)
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