Deleted Added
full compact
timeout.9 (141428) timeout.9 (147398)
1.\" $NetBSD: timeout.9,v 1.2 1996/06/23 22:32:34 pk Exp $
2.\"
3.\" Copyright (c) 1996 The NetBSD Foundation, Inc.
4.\" All rights reserved.
5.\"
6.\" This code is derived from software contributed to The NetBSD Foundation
7.\" by Paul Kranenburg.
8.\"
9.\" Redistribution and use in source and binary forms, with or without
10.\" modification, are permitted provided that the following conditions
11.\" are met:
12.\" 1. Redistributions of source code must retain the above copyright
13.\" notice, this list of conditions and the following disclaimer.
14.\" 2. Redistributions in binary form must reproduce the above copyright
15.\" notice, this list of conditions and the following disclaimer in the
16.\" documentation and/or other materials provided with the distribution.
17.\" 3. All advertising materials mentioning features or use of this software
18.\" must display the following acknowledgement:
19.\" This product includes software developed by the NetBSD
20.\" Foundation, Inc. and its contributors.
21.\" 4. Neither the name of The NetBSD Foundation nor the names of its
22.\" contributors may be used to endorse or promote products derived
23.\" from this software without specific prior written permission.
24.\"
25.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
26.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
29.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35.\" POSSIBILITY OF SUCH DAMAGE.
36.\"
1.\" $NetBSD: timeout.9,v 1.2 1996/06/23 22:32:34 pk Exp $
2.\"
3.\" Copyright (c) 1996 The NetBSD Foundation, Inc.
4.\" All rights reserved.
5.\"
6.\" This code is derived from software contributed to The NetBSD Foundation
7.\" by Paul Kranenburg.
8.\"
9.\" Redistribution and use in source and binary forms, with or without
10.\" modification, are permitted provided that the following conditions
11.\" are met:
12.\" 1. Redistributions of source code must retain the above copyright
13.\" notice, this list of conditions and the following disclaimer.
14.\" 2. Redistributions in binary form must reproduce the above copyright
15.\" notice, this list of conditions and the following disclaimer in the
16.\" documentation and/or other materials provided with the distribution.
17.\" 3. All advertising materials mentioning features or use of this software
18.\" must display the following acknowledgement:
19.\" This product includes software developed by the NetBSD
20.\" Foundation, Inc. and its contributors.
21.\" 4. Neither the name of The NetBSD Foundation nor the names of its
22.\" contributors may be used to endorse or promote products derived
23.\" from this software without specific prior written permission.
24.\"
25.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
26.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
29.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35.\" POSSIBILITY OF SUCH DAMAGE.
36.\"
37.\" $FreeBSD: head/share/man/man9/timeout.9 141428 2005-02-07 02:47:33Z iedowse $
37.\" $FreeBSD: head/share/man/man9/timeout.9 147398 2005-06-15 13:31:23Z ru $
38.\"
39.Dd February 6, 2005
40.Dt TIMEOUT 9
41.Os
42.Sh NAME
43.Nm timeout ,
44.Nm untimeout ,
45.Nm callout_handle_init ,
46.Nm callout_init ,
47.Nm callout_init_mtx ,
48.Nm callout_stop ,
49.Nm callout_drain ,
50.Nm callout_reset ,
51.Nm callout_pending ,
52.Nm callout_active ,
53.Nm callout_deactivate
54.Nd execute a function after a specified length of time
55.Sh SYNOPSIS
56.In sys/types.h
57.In sys/systm.h
58.Pp
59.Bd -literal
60typedef void timeout_t (void *);
61.Ed
62.Ft struct callout_handle
63.Fn timeout "timeout_t *func" "void *arg" "int ticks"
64.Ft void
65.Fn callout_handle_init "struct callout_handle *handle"
66.Pp
67.Bd -literal
68struct callout_handle handle = CALLOUT_HANDLE_INITIALIZER(&handle)
69.Ed
70.Ft void
71.Fn untimeout "timeout_t *func" "void *arg" "struct callout_handle handle"
72.Ft void
73.Fn callout_init "struct callout *c" "int mpsafe"
74.Ft void
75.Fn callout_init_mtx "struct callout *c" "struct mtx *mtx" "int flags"
76.Ft int
77.Fn callout_stop "struct callout *c"
78.Ft int
79.Fn callout_drain "struct callout *c"
80.Ft void
81.Fn callout_reset "struct callout *c" "int ticks" "timeout_t *func" "void *arg"
82.Ft int
83.Fn callout_pending "struct callout *c"
84.Ft int
85.Fn callout_active "struct callout *c"
86.Fn callout_deactivate "struct callout *c"
87.Sh DESCRIPTION
88The function
89.Fn timeout
90schedules a call to the function given by the argument
91.Fa func
92to take place after
93.Fa ticks Ns No /hz
94seconds.
95Non-positive values of
96.Fa ticks
97are silently converted to the value
98.Sq 1 .
99.Fa func
100should be a pointer to a function that takes a
101.Fa void *
102argument.
103Upon invocation,
104.Fa func
105will receive
106.Fa arg
107as its only argument.
108The return value from
109.Fn timeout
110is a
111.Ft struct callout_handle
112which can be used in conjunction with the
113.Fn untimeout
114function to request that a scheduled timeout be canceled.
115The
116.Fn timeout
117call is the old style and new code should use the
118.Fn callout_*
119functions.
120.Pp
121The function
122.Fn callout_handle_init
123can be used to initialize a handle to a state which will cause
124any calls to untimeout with that handle to return with no side
125effects.
126.Pp
127Assigning a callout handle the value of
128.Fn CALLOUT_HANDLE_INITIALIZER
129performs the same function as
130.Fn callout_handle_init
131and is provided for use on statically declared or global callout handles.
132.Pp
133The function
134.Fn untimeout
135cancels the timeout associated with
136.Fa handle
137using the
138.Fa func
139and
140.Fa arg
141arguments to validate the handle.
142If the handle does not correspond to a timeout with
143the function
144.Fa func
145taking the argument
146.Fa arg
147no action is taken.
148.Fa handle
149must be initialized by a previous call to
150.Fn timeout ,
151.Fn callout_handle_init ,
152or assigned the value of
153.Fn CALLOUT_HANDLE_INITIALIZER "&handle"
154before being passed to
155.Fn untimeout .
156The behavior of calling untimeout without a previously initialized handle
157is undefined.
158The
159.Fn untimeout
160call is the old style and new code should use the
161.Fn callout_*
162functions.
163.Pp
164As handles are recycled by the system, it is possible (although unlikely)
165that a handle from one invocation of
166.Fn timeout
167may match the handle of another invocation of
168.Fn timeout
169if both calls used the same function pointer and argument, and the first
170timeout is expired or canceled before the second call.
171The timeout facility offers O(1) running time for
172.Fn timeout
173and
174.Fn untimeout .
175Timeouts are executed from
176.Fn softclock
177with the
178.Va Giant
179lock held.
180Thus they are protected from re-entrancy.
181.Pp
182The functions
183.Fn callout_init ,
184.Fn callout_init_mtx ,
185.Fn callout_stop ,
186.Fn callout_drain
187and
188.Fn callout_reset
189are low-level routines for clients who wish to allocate their own
190callout structures.
191.Pp
192The function
193.Fn callout_init
194initializes a callout so it can be passed to
195.Fn callout_stop ,
196.Fn callout_drain
197or
198.Fn callout_reset
199without any side effects.
200If the
201.Fa mpsafe
202argument is zero,
203the callout structure is not considered to be
204.Dq multi-processor safe ;
205that is,
206the Giant lock will be acquired before calling the callout function,
207and released when the callout function returns.
208.Pp
209The
210.Fn callout_init_mtx
211function may be used as an alternative to
212.Fn callout_init .
213The parameter
214.Fa mtx
215specifies a mutex that is to be acquired by the callout subsystem
216before calling the callout function, and released when the callout
217function returns.
218The following
219.Fa flags
220may be specified:
38.\"
39.Dd February 6, 2005
40.Dt TIMEOUT 9
41.Os
42.Sh NAME
43.Nm timeout ,
44.Nm untimeout ,
45.Nm callout_handle_init ,
46.Nm callout_init ,
47.Nm callout_init_mtx ,
48.Nm callout_stop ,
49.Nm callout_drain ,
50.Nm callout_reset ,
51.Nm callout_pending ,
52.Nm callout_active ,
53.Nm callout_deactivate
54.Nd execute a function after a specified length of time
55.Sh SYNOPSIS
56.In sys/types.h
57.In sys/systm.h
58.Pp
59.Bd -literal
60typedef void timeout_t (void *);
61.Ed
62.Ft struct callout_handle
63.Fn timeout "timeout_t *func" "void *arg" "int ticks"
64.Ft void
65.Fn callout_handle_init "struct callout_handle *handle"
66.Pp
67.Bd -literal
68struct callout_handle handle = CALLOUT_HANDLE_INITIALIZER(&handle)
69.Ed
70.Ft void
71.Fn untimeout "timeout_t *func" "void *arg" "struct callout_handle handle"
72.Ft void
73.Fn callout_init "struct callout *c" "int mpsafe"
74.Ft void
75.Fn callout_init_mtx "struct callout *c" "struct mtx *mtx" "int flags"
76.Ft int
77.Fn callout_stop "struct callout *c"
78.Ft int
79.Fn callout_drain "struct callout *c"
80.Ft void
81.Fn callout_reset "struct callout *c" "int ticks" "timeout_t *func" "void *arg"
82.Ft int
83.Fn callout_pending "struct callout *c"
84.Ft int
85.Fn callout_active "struct callout *c"
86.Fn callout_deactivate "struct callout *c"
87.Sh DESCRIPTION
88The function
89.Fn timeout
90schedules a call to the function given by the argument
91.Fa func
92to take place after
93.Fa ticks Ns No /hz
94seconds.
95Non-positive values of
96.Fa ticks
97are silently converted to the value
98.Sq 1 .
99.Fa func
100should be a pointer to a function that takes a
101.Fa void *
102argument.
103Upon invocation,
104.Fa func
105will receive
106.Fa arg
107as its only argument.
108The return value from
109.Fn timeout
110is a
111.Ft struct callout_handle
112which can be used in conjunction with the
113.Fn untimeout
114function to request that a scheduled timeout be canceled.
115The
116.Fn timeout
117call is the old style and new code should use the
118.Fn callout_*
119functions.
120.Pp
121The function
122.Fn callout_handle_init
123can be used to initialize a handle to a state which will cause
124any calls to untimeout with that handle to return with no side
125effects.
126.Pp
127Assigning a callout handle the value of
128.Fn CALLOUT_HANDLE_INITIALIZER
129performs the same function as
130.Fn callout_handle_init
131and is provided for use on statically declared or global callout handles.
132.Pp
133The function
134.Fn untimeout
135cancels the timeout associated with
136.Fa handle
137using the
138.Fa func
139and
140.Fa arg
141arguments to validate the handle.
142If the handle does not correspond to a timeout with
143the function
144.Fa func
145taking the argument
146.Fa arg
147no action is taken.
148.Fa handle
149must be initialized by a previous call to
150.Fn timeout ,
151.Fn callout_handle_init ,
152or assigned the value of
153.Fn CALLOUT_HANDLE_INITIALIZER "&handle"
154before being passed to
155.Fn untimeout .
156The behavior of calling untimeout without a previously initialized handle
157is undefined.
158The
159.Fn untimeout
160call is the old style and new code should use the
161.Fn callout_*
162functions.
163.Pp
164As handles are recycled by the system, it is possible (although unlikely)
165that a handle from one invocation of
166.Fn timeout
167may match the handle of another invocation of
168.Fn timeout
169if both calls used the same function pointer and argument, and the first
170timeout is expired or canceled before the second call.
171The timeout facility offers O(1) running time for
172.Fn timeout
173and
174.Fn untimeout .
175Timeouts are executed from
176.Fn softclock
177with the
178.Va Giant
179lock held.
180Thus they are protected from re-entrancy.
181.Pp
182The functions
183.Fn callout_init ,
184.Fn callout_init_mtx ,
185.Fn callout_stop ,
186.Fn callout_drain
187and
188.Fn callout_reset
189are low-level routines for clients who wish to allocate their own
190callout structures.
191.Pp
192The function
193.Fn callout_init
194initializes a callout so it can be passed to
195.Fn callout_stop ,
196.Fn callout_drain
197or
198.Fn callout_reset
199without any side effects.
200If the
201.Fa mpsafe
202argument is zero,
203the callout structure is not considered to be
204.Dq multi-processor safe ;
205that is,
206the Giant lock will be acquired before calling the callout function,
207and released when the callout function returns.
208.Pp
209The
210.Fn callout_init_mtx
211function may be used as an alternative to
212.Fn callout_init .
213The parameter
214.Fa mtx
215specifies a mutex that is to be acquired by the callout subsystem
216before calling the callout function, and released when the callout
217function returns.
218The following
219.Fa flags
220may be specified:
221.Bl -tag -width CALLOUT_RETURNUNLOCKED
221.Bl -tag -width ".Dv CALLOUT_RETURNUNLOCKED"
222.It Dv CALLOUT_RETURNUNLOCKED
223The callout function will release
224.Fa mtx
225itself, so the callout subsystem should not attempt to unlock it
226after the callout function returns.
227.El
228.Pp
229The function
230.Fn callout_stop
231cancels a callout if it is currently pending.
232If the callout is pending, then
233.Fn callout_stop
234will return a non-zero value.
235If the callout is not set, has already been serviced or is currently
236being serviced, then zero will be returned.
237If the callout has an associated mutex, then that mutex must be
238held when this function is called.
239.Pp
240The function
241.Fn callout_drain
242is identical to
243.Fn callout_stop
244except that it will wait for the callout to be completed if it is
245already in progress.
246This function MUST NOT be called while holding any
247locks on which the callout might block, or deadlock will result.
248Note that if the callout subsystem has already begun processing this
249callout, then the callout function may be invoked during the execution of
250.Fn callout_drain .
251However, the callout subsystem does guarantee that the callout will be
252fully stopped before
253.Fn callout_drain
254returns.
255.Pp
256The function
257.Fn callout_reset
258first performs the equivalent of
259.Fn callout_stop
260to disestablish the callout, and then establishes a new callout in the
261same manner as
262.Fn timeout .
263If the callout has an associated mutex, then that mutex must be
264held when this function is called.
265.Pp
266The macros
267.Fn callout_pending ,
268.Fn callout_active
269and
270.Fn callout_deactivate
271provide access to the current state of the callout.
272Careful use of these macros can avoid many of the race conditions
273that are inherent in asynchronous timer facilities; see
274.Sx "Avoiding Race Conditions"
275below for further details.
276The
277.Fn callout_pending
278macro checks whether a callout is
279.Em pending ;
280a callout is considered
281.Em pending
282when a timeout has been set but the time has not yet arrived.
283Note that once the timeout time arrives and the callout subsystem
284starts to process this callout,
285.Fn callout_pending
286will return
287.Dv FALSE
288even though the callout function may not have finished (or even begun)
289executing.
290The
291.Fn callout_active
292macro checks whether a callout is marked as
293.Em active ,
294and the
295.Fn callout_deactivate
296macro clears the callout's
297.Em active
298flag.
299The callout subsystem marks a callout as
300.Em active
301when a timeout is set and it clears the
302.Em active
303flag in
304.Fn callout_stop
305and
306.Fn callout_drain ,
307but it
308.Em does not
309clear it when a callout expires normally via the execution of the
310callout function.
311.Ss "Avoiding Race Conditions"
312The callout subsystem invokes callout functions from its own timer
313context.
314Without some kind of synchronization it is possible that a callout
315function will be invoked concurrently with an attempt to stop or reset
316the callout by another thread.
317In particular, since callout functions typically acquire a mutex as
318their first action, the callout function may have already been invoked,
319but be blocked waiting for that mutex at the time that another thread
320tries to reset or stop the callout.
321.Pp
322The callout subsystem provides a number of mechanisms to address these
323synchronization concerns:
324.Bl -enum -offset indent
325.It
326If the callout has an associated mutex that was specified using the
327.Fn callout_init_mtx
328function (or implicitly specified as the
329.Va Giant
330mutex using
331.Fn callout_init
332with
333.Fa mpsafe
334set to
335.Dv FALSE ) ,
336then this mutex is used to avoid the race conditions.
337The associated mutex must be acquired by the caller before calling
338.Fn callout_stop
339or
340.Fn callout_reset
341and it is guaranteed that the callout will be correctly stopped
342or reset as expected.
343Note that it is still necessary to use
344.Fn callout_drain
345before destroying the callout or its associated mutex.
346.It
347The return value from
348.Fn callout_stop
349indicates whether or not the callout was removed.
350If it is known that the callout was set and the callout function has
351not yet executed, then a return value of
352.Dv FALSE
353indicates that the callout function is about to be called.
354For example:
355.Bd -literal -offset indent
356if (sc->sc_flags & SCFLG_CALLOUT_RUNNING) {
357 if (callout_stop(&sc->sc_callout)) {
358 sc->sc_flags &= ~SCFLG_CALLOUT_RUNNING;
359 /* successfully stopped */
360 } else {
361 /*
362 * callout has expired and callout
363 * function is about to be executed
364 */
365 }
366}
367.Ed
368.Pp
369Note that there is no equivalent mechanism to determine whether or not
370.Fn callout_reset
371stopped the callout.
372.It
373The
374.Fn callout_pending ,
375.Fn callout_active
376and
377.Fn callout_deactivate
378macros can be used together to work around the race conditions.
379When a callout's timeout is set, the callout subsystem marks the
380callout as both
381.Em active
382and
383.Em pending .
384When the timeout time arrives, the callout subsystem begins processing
385the callout by first clearing the
386.Em pending
387flag.
388It then invokes the callout function without changing the
389.Em active
390flag, and does not clear the
391.Em active
392flag even after the callout function returns.
393The mechanism described here requires the callout function itself to
394clear the
395.Em active
396flag using the
397.Fn callout_deactivate
398macro.
399The
400.Fn callout_stop
401and
402.Fn callout_drain
403functions always clear both the
404.Em active
405and
406.Em pending
407flags before returning.
408.Pp
409The callout function should first check the
410.Em pending
411flag and return without action if
412.Fn callout_pending
413returns
414.Dv TRUE .
415This indicates that the callout was rescheduled using
416.Fn callout_reset
417just before the callout function was invoked.
418If
419.Fn callout_active
420returns
421.Dv FALSE
422then the callout function should also return without action.
423This indicates that the callout has been stopped.
424Finally, the callout function should call
425.Fn callout_deactivate
426to clear the
427.Em active
428flag.
429For example:
430.Bd -literal -offset indent
431mtx_lock(&sc->sc_mtx);
432if (callout_pending(&sc->sc_callout)) {
433 /* callout was reset */
434 mtx_unlock(&sc->sc_mtx);
435 return;
436}
437if (!callout_active(&sc->sc_callout)) {
438 /* callout was stopped */
439 mtx_unlock(&sc->sc_mtx);
440 return;
441}
442callout_deactivate(&sc->sc_callout);
443/* rest of callout function */
444.Ed
445.Pp
446Together with appropriate synchronization, such as the mutex used above,
447this approach permits the
448.Fn callout_stop
449and
450.Fn callout_reset
451functions to be used at any time without races.
452For example:
453.Bd -literal -offset indent
454mtx_lock(&sc->sc_mtx);
455callout_stop(&sc->sc_callout);
456/* The callout is effectively stopped now. */
457.Ed
458.Pp
459If the callout is still pending then these functions operate normally,
460but if processing of the callout has already begun then the tests in
461the callout function cause it to return without further action.
462Synchronization between the callout function and other code ensures that
463stopping or resetting the callout will never be attempted while the
464callout function is past the
465.Fn callout_deactivate
466call.
467.Pp
468The above technique additionally ensures that the
469.Em active
470flag always reflects whether the callout is effectively enabled or
471disabled.
472If
473.Fn callout_active
474returns false, then the callout is effectively disabled, since even if
475the callout subsystem is actually just about to invoke the callout
476function, the callout function will return without action.
477.El
478.Pp
479There is one final race condition that must be considered when a
480callout is being stopped for the last time.
481In this case it may not be safe to let the callout function itself
482detect that the callout was stopped, since it may need to access
483data objects that have already been destroyed or recycled.
484To ensure that the callout is completely finished, a call to
485.Fn callout_drain
486should be used.
487.Sh RETURN VALUES
488The
489.Fn timeout
490function returns a
491.Ft struct callout_handle
492that can be passed to
493.Fn untimeout .
494The
495.Fn callout_stop
496and
497.Fn callout_drain
498functions return non-zero if the callout was still pending when it was
499called or zero otherwise.
500.Sh HISTORY
501The current timeout and untimeout routines are based on the work of
502.An Adam M. Costello
503and
504.An George Varghese ,
505published in a technical report entitled
506.%T "Redesigning the BSD Callout and Timer Facilities"
507and modified slightly for inclusion in
508.Fx
509by
510.An Justin T. Gibbs .
511The original work on the data structures used in this implementation
512was published by
513.An G. Varghese
514and
515.An A. Lauck
516in the paper
517.%T "Hashed and Hierarchical Timing Wheels: Data Structures for the Efficient Implementation of a Timer Facility"
518in the
519.%B "Proceedings of the 11th ACM Annual Symposium on Operating Systems Principles" .
520The current implementation replaces the long standing
521.Bx
522linked list
523callout mechanism which offered O(n) insertion and removal running time
524but did not generate or require handles for untimeout operations.
222.It Dv CALLOUT_RETURNUNLOCKED
223The callout function will release
224.Fa mtx
225itself, so the callout subsystem should not attempt to unlock it
226after the callout function returns.
227.El
228.Pp
229The function
230.Fn callout_stop
231cancels a callout if it is currently pending.
232If the callout is pending, then
233.Fn callout_stop
234will return a non-zero value.
235If the callout is not set, has already been serviced or is currently
236being serviced, then zero will be returned.
237If the callout has an associated mutex, then that mutex must be
238held when this function is called.
239.Pp
240The function
241.Fn callout_drain
242is identical to
243.Fn callout_stop
244except that it will wait for the callout to be completed if it is
245already in progress.
246This function MUST NOT be called while holding any
247locks on which the callout might block, or deadlock will result.
248Note that if the callout subsystem has already begun processing this
249callout, then the callout function may be invoked during the execution of
250.Fn callout_drain .
251However, the callout subsystem does guarantee that the callout will be
252fully stopped before
253.Fn callout_drain
254returns.
255.Pp
256The function
257.Fn callout_reset
258first performs the equivalent of
259.Fn callout_stop
260to disestablish the callout, and then establishes a new callout in the
261same manner as
262.Fn timeout .
263If the callout has an associated mutex, then that mutex must be
264held when this function is called.
265.Pp
266The macros
267.Fn callout_pending ,
268.Fn callout_active
269and
270.Fn callout_deactivate
271provide access to the current state of the callout.
272Careful use of these macros can avoid many of the race conditions
273that are inherent in asynchronous timer facilities; see
274.Sx "Avoiding Race Conditions"
275below for further details.
276The
277.Fn callout_pending
278macro checks whether a callout is
279.Em pending ;
280a callout is considered
281.Em pending
282when a timeout has been set but the time has not yet arrived.
283Note that once the timeout time arrives and the callout subsystem
284starts to process this callout,
285.Fn callout_pending
286will return
287.Dv FALSE
288even though the callout function may not have finished (or even begun)
289executing.
290The
291.Fn callout_active
292macro checks whether a callout is marked as
293.Em active ,
294and the
295.Fn callout_deactivate
296macro clears the callout's
297.Em active
298flag.
299The callout subsystem marks a callout as
300.Em active
301when a timeout is set and it clears the
302.Em active
303flag in
304.Fn callout_stop
305and
306.Fn callout_drain ,
307but it
308.Em does not
309clear it when a callout expires normally via the execution of the
310callout function.
311.Ss "Avoiding Race Conditions"
312The callout subsystem invokes callout functions from its own timer
313context.
314Without some kind of synchronization it is possible that a callout
315function will be invoked concurrently with an attempt to stop or reset
316the callout by another thread.
317In particular, since callout functions typically acquire a mutex as
318their first action, the callout function may have already been invoked,
319but be blocked waiting for that mutex at the time that another thread
320tries to reset or stop the callout.
321.Pp
322The callout subsystem provides a number of mechanisms to address these
323synchronization concerns:
324.Bl -enum -offset indent
325.It
326If the callout has an associated mutex that was specified using the
327.Fn callout_init_mtx
328function (or implicitly specified as the
329.Va Giant
330mutex using
331.Fn callout_init
332with
333.Fa mpsafe
334set to
335.Dv FALSE ) ,
336then this mutex is used to avoid the race conditions.
337The associated mutex must be acquired by the caller before calling
338.Fn callout_stop
339or
340.Fn callout_reset
341and it is guaranteed that the callout will be correctly stopped
342or reset as expected.
343Note that it is still necessary to use
344.Fn callout_drain
345before destroying the callout or its associated mutex.
346.It
347The return value from
348.Fn callout_stop
349indicates whether or not the callout was removed.
350If it is known that the callout was set and the callout function has
351not yet executed, then a return value of
352.Dv FALSE
353indicates that the callout function is about to be called.
354For example:
355.Bd -literal -offset indent
356if (sc->sc_flags & SCFLG_CALLOUT_RUNNING) {
357 if (callout_stop(&sc->sc_callout)) {
358 sc->sc_flags &= ~SCFLG_CALLOUT_RUNNING;
359 /* successfully stopped */
360 } else {
361 /*
362 * callout has expired and callout
363 * function is about to be executed
364 */
365 }
366}
367.Ed
368.Pp
369Note that there is no equivalent mechanism to determine whether or not
370.Fn callout_reset
371stopped the callout.
372.It
373The
374.Fn callout_pending ,
375.Fn callout_active
376and
377.Fn callout_deactivate
378macros can be used together to work around the race conditions.
379When a callout's timeout is set, the callout subsystem marks the
380callout as both
381.Em active
382and
383.Em pending .
384When the timeout time arrives, the callout subsystem begins processing
385the callout by first clearing the
386.Em pending
387flag.
388It then invokes the callout function without changing the
389.Em active
390flag, and does not clear the
391.Em active
392flag even after the callout function returns.
393The mechanism described here requires the callout function itself to
394clear the
395.Em active
396flag using the
397.Fn callout_deactivate
398macro.
399The
400.Fn callout_stop
401and
402.Fn callout_drain
403functions always clear both the
404.Em active
405and
406.Em pending
407flags before returning.
408.Pp
409The callout function should first check the
410.Em pending
411flag and return without action if
412.Fn callout_pending
413returns
414.Dv TRUE .
415This indicates that the callout was rescheduled using
416.Fn callout_reset
417just before the callout function was invoked.
418If
419.Fn callout_active
420returns
421.Dv FALSE
422then the callout function should also return without action.
423This indicates that the callout has been stopped.
424Finally, the callout function should call
425.Fn callout_deactivate
426to clear the
427.Em active
428flag.
429For example:
430.Bd -literal -offset indent
431mtx_lock(&sc->sc_mtx);
432if (callout_pending(&sc->sc_callout)) {
433 /* callout was reset */
434 mtx_unlock(&sc->sc_mtx);
435 return;
436}
437if (!callout_active(&sc->sc_callout)) {
438 /* callout was stopped */
439 mtx_unlock(&sc->sc_mtx);
440 return;
441}
442callout_deactivate(&sc->sc_callout);
443/* rest of callout function */
444.Ed
445.Pp
446Together with appropriate synchronization, such as the mutex used above,
447this approach permits the
448.Fn callout_stop
449and
450.Fn callout_reset
451functions to be used at any time without races.
452For example:
453.Bd -literal -offset indent
454mtx_lock(&sc->sc_mtx);
455callout_stop(&sc->sc_callout);
456/* The callout is effectively stopped now. */
457.Ed
458.Pp
459If the callout is still pending then these functions operate normally,
460but if processing of the callout has already begun then the tests in
461the callout function cause it to return without further action.
462Synchronization between the callout function and other code ensures that
463stopping or resetting the callout will never be attempted while the
464callout function is past the
465.Fn callout_deactivate
466call.
467.Pp
468The above technique additionally ensures that the
469.Em active
470flag always reflects whether the callout is effectively enabled or
471disabled.
472If
473.Fn callout_active
474returns false, then the callout is effectively disabled, since even if
475the callout subsystem is actually just about to invoke the callout
476function, the callout function will return without action.
477.El
478.Pp
479There is one final race condition that must be considered when a
480callout is being stopped for the last time.
481In this case it may not be safe to let the callout function itself
482detect that the callout was stopped, since it may need to access
483data objects that have already been destroyed or recycled.
484To ensure that the callout is completely finished, a call to
485.Fn callout_drain
486should be used.
487.Sh RETURN VALUES
488The
489.Fn timeout
490function returns a
491.Ft struct callout_handle
492that can be passed to
493.Fn untimeout .
494The
495.Fn callout_stop
496and
497.Fn callout_drain
498functions return non-zero if the callout was still pending when it was
499called or zero otherwise.
500.Sh HISTORY
501The current timeout and untimeout routines are based on the work of
502.An Adam M. Costello
503and
504.An George Varghese ,
505published in a technical report entitled
506.%T "Redesigning the BSD Callout and Timer Facilities"
507and modified slightly for inclusion in
508.Fx
509by
510.An Justin T. Gibbs .
511The original work on the data structures used in this implementation
512was published by
513.An G. Varghese
514and
515.An A. Lauck
516in the paper
517.%T "Hashed and Hierarchical Timing Wheels: Data Structures for the Efficient Implementation of a Timer Facility"
518in the
519.%B "Proceedings of the 11th ACM Annual Symposium on Operating Systems Principles" .
520The current implementation replaces the long standing
521.Bx
522linked list
523callout mechanism which offered O(n) insertion and removal running time
524but did not generate or require handles for untimeout operations.