xref: /freebsd/share/man/man9/sleepqueue.9 (revision 6af83ee0d2941d18880b6aaa2b4facd1d30c6106)
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_lookup ,
39.Nm sleepq_release ,
40.Nm sleepq_remove ,
41.Nm sleepq_signal ,
42.Nm sleepq_set_timeout ,
43.Nm sleepq_timedwait ,
44.Nm sleepq_timedwait_sig ,
45.Nm sleepq_wait ,
46.Nm sleepq_wait_sig
47.Nd manage the queues of sleeping threads
48.Sh SYNOPSIS
49.In sys/param.h
50.In sys/sleepqueue.h
51.Ft void
52.Fn init_sleepqueues "void"
53.Ft void
54.Fn sleepq_abort "struct thread *td"
55.Ft void
56.Fn sleepq_add "struct sleepqueue *sq" "void *wchan" "struct mtx *lock" "const char *wmesg" "int flags"
57.Ft struct sleepqueue *
58.Fn sleepq_alloc "void"
59.Ft void
60.Fn sleepq_broadcast "void *wchan" "int flags" "int pri"
61.Ft int
62.Fn sleepq_calc_signal_retval "int sig"
63.Ft int
64.Fn sleepq_catch_signals "void *wchan"
65.Ft void
66.Fn sleepq_free "struct sleepqueue *sq"
67.Ft struct sleepqueue *
68.Fn sleepq_lookup "void *wchan"
69.Ft void
70.Fn sleepq_release "void *wchan"
71.Ft void
72.Fn sleepq_remove "struct thread *td" "void *wchan"
73.Ft void
74.Fn sleepq_signal "void *wchan" "int flags" "int pri"
75.Ft void
76.Fn sleepq_set_timeout "void *wchan" "int timo"
77.Ft int
78.Fn sleepq_timedwait "void *wchan"
79.Ft int
80.Fn sleepq_timedwait_sig "void *wchan" "int signal_caught"
81.Ft void
82.Fn sleepq_wait "void *wchan"
83.Ft int
84.Fn sleepq_wait_sig "void *wchan"
85.Sh DESCRIPTION
86Sleep queues provide a mechanism for suspending execution of a thread until
87some condition is met.
88Each queue is associated with a specific wait channel when it is active,
89and only one queue may be associated with a wait channel at any given point
90in time.
91An active queue holds a list of threads that are blocked on the associated
92wait channel.
93Threads that are not blocked on a wait channel have an associated inactive
94sleep queue.
95When a thread blocks on a wait channel it donates its inactive sleep queue
96to the wait channel.
97When a thread is resumed,
98the wait channel that it was blocked on gives it an inactive sleep queue for
99later use.
100The
101.Fn sleepq_alloc
102allocates an inactive sleep queue and is used to assign a sleep queue to a
103thread during thread creation.
104The
105.Fn sleepq_free
106function frees the resources associated with an inactive sleep queue and is
107used to free a queue during thread destruction.
108.Pp
109Active sleep queues are stored in a hash table hashed on the addresses pointed
110to by wait channels.
111Each bucket in the hash table contains a sleep queue chain.
112A sleep queue chain contains a spin mutex and a list of sleep queues that hash
113to that specific chain.
114Active sleep queues are protected by their chain's spin mutex.
115The
116.Fn init_sleepqueues
117function initializes the hash table of sleep queue chains.
118.Pp
119The
120.Fn sleepq_lookup
121function locks the sleep queue chain associated with
122.Fa wchan
123and returns a pointer to the current active sleep queue for that wait channel
124or
125.Dv NULL
126if there currently is not an active sleep queue.
127The
128.Fn sleepq_release
129function unlocks the sleep queue chain associated with
130.Fn wchan
131and is primarily useful when aborting a pending sleep request before one of
132the wait functions is called.
133.Pp
134The
135.Fn sleepq_add
136function places the current thread on the sleep queue associated with the
137wait channel
138.Fa wchan .
139The associated sleep queue chain must be locked by a call to
140.Fn sleepq_lookup
141when this function is called and its return value should be passed as the
142.Fa sq
143parameter.
144If a mutex is specified via the
145.Fa lock
146argument, then the sleep queue code will perform extra checks to ensure that
147the mutex is held for all threads sleeping on
148.Fa wchan .
149The
150.Fa wmesg
151parameter should be a short description of
152.Fa wchan .
153The
154.Fa flags
155parameter is a bitmask consisting of the type of sleep queue being slept on
156and zero or more optional flags.
157There are currently two types of sleep queues:
158.Bl -tag -width ".Dv SLEEPQ_CONDVAR"
159.It Dv SLEEPQ_CONDVAR
160A sleep queue used to implement condition variables.
161.It Dv SLEEPQ_MSLEEP
162A sleep queue used to implement
163.Xr msleep 9 ,
164.Xr wakeup 9
165and
166.Xr wakeup_one 9 .
167.El
168.Pp
169There is currently only one optional flag:
170.Bl -tag -width ".Dv SLEEPQ_INTERRUPTIBLE"
171.It Dv SLEEPQ_INTERRUPTIBLE
172The current thread is entering an interruptible sleep.
173.El
174.Pp
175A timeout on the sleep may be specified by calling
176.Fn sleepq_set_timeout
177after
178.Fn sleepq_add .
179The
180.Fa wchan
181parameter should be the same value from the preceding call to
182.Fn sleepq_add .
183The
184.Fa timo
185parameter should specify the timeout value in ticks.
186The thread may be marked interruptible by calling
187.Fn sleepq_catch_signals
188with
189.Fa wchan
190set to the wait channel.
191The function returns a signal number if there are any pending signals for
192the current thread and 0 if there is not a pending signal.
193.Pp
194Once the thread is ready to suspend,
195one of the wait functions is called to put the thread to sleep until it is
196awakened and context switch to another thread.
197The
198.Fn sleepq_wait
199function is used for non-interruptible sleeps that do not have a timeout.
200The
201.Fn sleepq_timedwait
202function is used for non-interruptible sleeps that have had a timeout set via
203.Fn sleepq_set_timeout .
204The
205.Fn sleepq_wait_sig
206function is used for interruptible sleeps that do not have a timeout.
207The
208.Fn sleepq_timedwait_sig
209function is used for interruptible sleeps that do have a timeout set.
210The
211.Fa wchan
212argument to all of the wait functions is the wait channel being slept on.
213The
214.Fa signal_caught
215parameter to
216.Fn sleepq_timedwait_sig
217specifies if a previous call to
218.Fn sleepq_catch_signals
219found a pending signal.
220.Pp
221When the thread is resumed,
222the wait functions return a non-zero value if the thread was awakened due to
223an interrupt other than a signal or a timeout.
224If the sleep timed out, then
225.Er EWOULDBLOCK
226is returned.
227If the sleep was interrupted by something other than a signal,
228then some other return value will be returned.
229If zero is returned after resuming from an interruptible sleep,
230then
231.Fn sleepq_calc_signal_retval
232should be called to determine if the sleep was interrupted by a signal.
233If so,
234.Fn sleepq_calc_signal_retval
235returns
236.Er ERESTART
237if the interrupting signal is restartable and
238.Er EINTR
239otherwise.
240If the sleep was not interrupted by a signal,
241.Fn sleepq_calc_signal_retval
242will return 0.
243.Pp
244A sleeping thread is normally resumed by the
245.Fn sleepq_broadcast
246and
247.Fn sleepq_signal
248functions.
249The
250.Fn sleepq_signal
251function awakens the highest priority thread sleeping on a wait channel while
252.Fn sleepq_broadcast
253awakens all of the threads sleeping on a wait channel.
254The
255.Fa wchan
256argument specifics which wait channel to awaken.
257The
258.Fa flags
259argument must match the sleep queue type contained in the
260.Fa flags
261argument passed to
262.Fn sleepq_add
263by the threads sleeping on the wait channel.
264If the
265.Fa pri
266argument does not equal \-1,
267then each thread that is awakened will have its priority raised to
268.Fa pri
269if it has a lower priority.
270.Pp
271A thread in an interruptible sleep can be interrupted by another thread via
272the
273.Fn sleepq_abort
274function.
275The
276.Fa td
277argument specifies the thread to interrupt.
278An individual thread can also be awakened from sleeping on a specific wait
279channel via the
280.Fn sleepq_remove
281function.
282The
283.Fa td
284argument specifies the thread to awaken and the
285.Fa wchan
286argument specifies the wait channel to awaken it from.
287If the thread
288.Fa td
289is not blocked on the the wait channel
290.Fa wchan
291then this function will not do anything,
292even if the thread is asleep on a different wait channel.
293This function should only be used if one of the other functions above is not
294sufficient.
295One possible use is waking up a specific thread from a widely shared sleep
296channel.
297.Pp
298The sleep queue interface is currently used to implement the
299.Xr msleep 9
300and
301.Xr condvar 9
302interfaces.
303Almost all other code in the kernel should use one of those interfaces rather
304than manipulating sleep queues directly.
305.Sh SEE ALSO
306.Xr condvar 9 ,
307.Xr msleep 9 ,
308.Xr runqueue 9 ,
309.Xr scheduler 9
310