xref: /dragonfly/share/man/man9/callout.9 (revision f9993810)
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.\"
18.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
19.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21.\" PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
22.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28.\" POSSIBILITY OF SUCH DAMAGE.
29.\"
30.Dd April 15, 2022
31.Dt CALLOUT 9
32.Os
33.Sh NAME
34.Nm callout_active ,
35.Nm callout_deactivate ,
36.Nm callout_drain ,
37.Nm callout_init ,
38.Nm callout_init_mp ,
39.Nm callout_init_lk ,
40.Nm callout_pending ,
41.Nm callout_reset ,
42.Nm callout_reset_bycpu ,
43.Nm callout_stop ,
44.Nm callout_stop_async ,
45.Nm callout_cancel ,
46.Nm callout_terminate
47.Nd execute a function after a specified length of time
48.Sh SYNOPSIS
49.In sys/types.h
50.In sys/systm.h
51.In sys/callout.h
52.Bd -literal
53typedef void timeout_t (void *);
54.Ed
55.Ft int
56.Fn callout_active "struct callout *c"
57.Ft void
58.Fn callout_deactivate "struct callout *c"
59.Ft int
60.Fn callout_drain "struct callout *c"
61.Ft void
62.Fn callout_init "struct callout *c"
63.Ft void
64.Fn callout_init_mp "struct callout *c"
65.Ft void
66.Fn callout_init_lk "struct callout *c" "struct lock *lk"
67.Ft int
68.Fn callout_pending "struct callout *c"
69.Ft void
70.Fn callout_reset "struct callout *c" "int ticks" "timeout_t *func" "void *arg"
71.Ft void
72.Fo callout_reset_bycpu
73.Fa "struct callout *c"
74.Fa "int ticks"
75.Fa "timeout_t *func"
76.Fa "void *arg"
77.Fa "int cpuid"
78.Fc
79.Ft int
80.Fn callout_stop "struct callout *c"
81.Ft int
82.Fn callout_stop_async "struct callout *c"
83.Ft int
84.Fn callout_cancel "struct callout *c"
85.Ft void
86.Fn callout_terminate "struct callout *c"
87.Sh DESCRIPTION
88The
89.Nm callout
90API is used to schedule a call to an arbitrary function at a specific
91time in the future.
92Consumers of this API are required to allocate a callout structure
93.Pq struct callout
94for each pending function invocation.
95This structure stores state about the pending function invocation including
96the function to be called and the time at which the function should be invoked.
97Pending function calls can be cancelled or rescheduled to a different time.
98In addition,
99a callout structure may be reused to schedule a new function call after a
100scheduled call is completed.
101.Pp
102Callouts only provide a single-shot mode.
103If a consumer requires a periodic timer,
104it must explicitly reschedule each function call.
105This is normally done by rescheduling the subsequent call within the called
106function.
107.Pp
108In
109.Fx
110callout functions must not sleep.
111They may not acquire sleepable locks,
112wait on condition variables,
113perform blocking allocation requests,
114or invoke any other action that might sleep.
115In
116.Dx
117all callout functions are executed from a common kernel thread on the
118target CPU and may block as long as deadlocks are avoided.
119But generally speaking,
120callout functions should run in as short a time as possible
121as they can add lag to other unrelated callouts.
122.Pp
123Each callout structure must be initialized by
124.Fn callout_init ,
125.Fn callout_init_mp ,
126or
127.Fn callout_init_lk
128before it is passed to any of the other callout functions.
129The
130.Fn callout_init
131and
132.Fn callout_init_mp
133functions initialize a callout structure in
134.Fa c
135that is not associated with a specific lock.
136The former will hold the mplock across callback.
137However, it is deprecated
138and should not be used in new code.
139.Fn callout_init_mp
140should be used for any new code.
141.Pp
142The
143.Fn callout_init_lk
144function initialize a callout structure in
145.Fa c
146that is associated with a specific lock.
147In
148.Fx
149the associated lock should be held while stopping or rescheduling the
150callout.
151In
152.Dx
153the same is true, but is not a requirement.
154.Pp
155The callout subsystem acquires the associated lock before calling the
156callout function and releases it after the function returns.
157If the callout was cancelled while the callout subsystem waited for the
158associated lock,
159the callout function is not called,
160and the associated lock is released.
161This ensures that stopping or rescheduling the callout will abort any
162previously scheduled invocation.
163.Pp
164The function
165.Fn callout_stop
166cancels a callout
167.Fa c
168if it is currently pending.
169If the callout is pending and successfully stopped, then
170.Fn callout_stop
171returns a value of one.
172In
173.Fx
174if the callout is not set, or
175has already been serviced, then
176negative one is returned.
177In
178.Dx
179if the callout is not set, or
180has already been serviced, then
181zero is returned.
182If the callout is currently being serviced and cannot be stopped,
183then zero will be returned.
184If the callout is currently being serviced and cannot be stopped, and at the
185same time a next invocation of the same callout is also scheduled, then
186.Fn callout_stop
187unschedules the next run and returns zero.
188In
189.Fx
190if the callout has an associated lock,
191then that lock must be held when this function is called.
192In
193.Dx
194if the callout has an associated lock,
195then that lock should be held when this function is called
196to avoid races, but does not have to be.
197.Pp
198In
199.Dx
200the stop operation is guaranteed to be synchronous if the callout
201was initialized with
202.Fn callout_init_lk .
203.Pp
204The function
205.Fn callout_stop_async
206is identical to
207.Fn callout_stop
208but does not block and allows the STOP operation to be asynchronous,
209meaning that the callout structure may still be relevant after the
210function returns.
211This situation can occur if the callback was
212in-progress at the time the stop was issued.
213.Pp
214The function
215.Fn callout_cancel
216synchronously cancels a callout and returns a value similar to that
217of
218.Fn callout_stop .
219.Fn callout_cancel
220overrides all other operations while it is in-progress.
221.Pp
222The function
223.Fn callout_terminate
224synchronously cancels a callout and informs the system that the
225callout structure will no longer be referenced.
226This function will clear the initialization flag and any further use of
227the callout structure will panic the system until it is next initialized.
228The callout structure can be safely freed after this function returns,
229assuming other program references to it have been removed.
230.Pp
231The function
232.Fn callout_drain
233is identical to
234.Fn callout_stop
235except that it will wait for the callout
236.Fa c
237to complete if it is already in progress.
238This function MUST NOT be called while holding any
239locks on which the callout might block, or deadlock will result.
240Note that if the callout subsystem has already begun processing this
241callout, then the callout function may be invoked before
242.Fn callout_drain
243returns.
244However, the callout subsystem does guarantee that the callout will be
245fully stopped before
246.Fn callout_drain
247returns.
248.Pp
249The
250.Fn callout_reset
251function schedules a future function invocation for callout
252.Fa c .
253If
254.Fa c
255already has a pending callout,
256it is cancelled before the new invocation is scheduled.
257In
258.Fx
259this function returns a value of one if a pending callout was cancelled
260and zero if there was no pending callout.
261If the callout has an associated lock,
262then that lock must be held when any of these functions are called.
263In
264.Dx
265this function returns void.
266If the callout has an associated lock,
267then that lock should generally be held when any of these functions are
268called, but the API will work either way.
269If a callout is already in-progress, this function's parameters will be
270applied when the in-progress callback returns, if not overridden from
271within the callback.
272.Pp
273The time at which the callout function will be invoked is determined by
274the
275.Fa ticks
276argument.
277The callout is scheduled to execute after
278.Fa ticks Ns No /hz
279seconds.
280Non-positive values of
281.Fa ticks
282are silently converted to the value
283.Sq 1 .
284.Pp
285The
286.Fn callout_reset_bycpu
287function schedules the callout to occur on the target CPU.
288The normal
289.Fn callout_reset
290function schedules the callout to occur on the current CPU.
291These functions accept a
292.Fa func
293argument which identifies the function to be called when the time expires.
294It must be a pointer to a function that takes a single
295.Fa void *
296argument.
297Upon invocation,
298.Fa func
299will receive
300.Fa arg
301as its only argument.
302.Pp
303The callout subsystem provides a softclock thread for each CPU in the system.
304Callouts are assigned to a single CPU and are executed by the softclock thread
305for that CPU.
306The callouts are assigned to the current CPU or to a specific CPU
307depending on the call.
308.Pp
309The
310.Fn callout_pending ,
311.Fn callout_active
312and
313.Fn callout_deactivate
314functions provide access to the current state of the callout.
315The
316.Fn callout_pending
317function checks whether a callout is
318.Em pending ;
319a callout is considered
320.Em pending
321when a timeout has been set but the time has not yet arrived.
322Note that once the timeout time arrives and the callout subsystem
323starts to process this callout,
324.Fn callout_pending
325will return
326.Dv FALSE
327even though the callout function may not have finished
328.Pq or even begun
329executing.
330The
331.Fn callout_active
332function checks whether a callout is marked as
333.Em active ,
334and the
335.Fn callout_deactivate
336function clears the callout's
337.Em active
338flag.
339The callout subsystem marks a callout as
340.Em active
341when a timeout is set and it clears the
342.Em active
343flag in
344.Fn callout_stop
345and
346.Fn callout_drain ,
347but it
348.Em does not
349clear it when a callout expires normally via the execution of the
350callout function.
351.Pp
352There are two main techniques for addressing these
353synchronization concerns.
354The first approach is preferred as it is the simplest:
355.Bl -enum -offset indent
356.It
357Callouts can be associated with a specific lock when they are initialized
358by
359.Fn callout_init_lk
360When a callout is associated with a lock,
361the callout subsystem acquires the lock before the callout function is
362invoked.
363This allows the callout subsystem to transparently handle races between
364callout cancellation,
365scheduling,
366and execution.
367Note that the associated lock must be acquired before calling
368.Fn callout_stop
369or
370.Fn callout_reset
371functions to provide this safety.
372.It
373The
374.Fn callout_pending ,
375.Fn callout_active
376and
377.Fn callout_deactivate
378functions can be used together to work around the race conditions,
379but the interpretation of these calls can be confusing and it
380is recommended that a different, caller-specific method be used to
381determine whether a race condition is present.
382.Pp
383When a callout's timeout is set, the callout subsystem marks the
384callout as both
385.Em active
386and
387.Em pending .
388When the timeout time arrives, the callout subsystem begins processing
389the callout by first clearing the
390.Em pending
391flag.
392It then invokes the callout function without changing the
393.Em active
394flag, and does not clear the
395.Em active
396flag even after the callout function returns.
397The mechanism described here requires the callout function itself to
398clear the
399.Em active
400flag using
401.Fn callout_deactivate .
402The
403.Fn callout_stop
404and
405.Fn callout_drain
406functions always clear both the
407.Em active
408and
409.Em pending
410flags before returning.
411.Pp
412The callout function should first check the
413.Em pending
414flag and return without action if
415.Fn callout_pending
416returns
417.Dv TRUE .
418This indicates that the callout was rescheduled using
419.Fn callout_reset
420just before the callout function was invoked.
421If
422.Fn callout_active
423returns
424.Dv FALSE
425then the callout function should also return without action.
426This indicates that the callout has been stopped.
427Finally, the callout function should call
428.Fn callout_deactivate
429to clear the
430.Em active
431flag.
432For example:
433.Bd -literal -offset indent
434lockmgr(&sc->sc_lock, LK_EXCLUSIVE);
435if (callout_pending(&sc->sc_callout)) {
436	/* callout was reset */
437	lockmgr(&sc->sc_lock, LK_RELEASE);
438	return;
439}
440if (!callout_active(&sc->sc_callout)) {
441	/* callout was stopped */
442	lockmgr(&sc->sc_lock, LK_RELEASE);
443	return;
444}
445callout_deactivate(&sc->sc_callout);
446/* rest of callout function */
447.Ed
448.Pp
449Together with appropriate synchronization, such as the lock used above,
450this approach permits the
451.Fn callout_stop
452and
453.Fn callout_reset
454functions to be used at any time without races.
455For example:
456.Bd -literal -offset indent
457lockmgr(&sc->sc_mtx, LK_EXCLUSIVE);
458callout_stop(&sc->sc_callout);
459/* The callout is effectively stopped now. */
460.Ed
461.Pp
462If the callout is still pending then these functions operate normally,
463but if processing of the callout has already begun then the tests in
464the callout function cause it to return without further action.
465Synchronization between the callout function and other code ensures that
466stopping or resetting the callout will never be attempted while the
467callout function is past the
468.Fn callout_deactivate
469call.
470.Pp
471The above technique additionally ensures that the
472.Em active
473flag always reflects whether the callout is effectively enabled or
474disabled.
475If
476.Fn callout_active
477returns false, then the callout is effectively disabled, since even if
478the callout subsystem is actually just about to invoke the callout
479function, the callout function will return without action.
480.El
481.Pp
482There is one final race condition that must be considered when a
483callout is being stopped for the last time.
484In this case it may not be safe to let the callout function itself
485detect that the callout was stopped, since it may need to access
486data objects that have already been destroyed or recycled.
487To ensure that the callout is completely inactive, a call to
488.Fn callout_cancel
489or
490.Fn callout_terminate
491should be used.
492.Sh RETURN VALUES
493The
494.Fn callout_active
495function returns the state of a callout's
496.Em active
497flag.
498.Pp
499The
500.Fn callout_pending
501function returns the state of a callout's
502.Em pending
503flag.
504.Pp
505The
506.Fn callout_cancel ,
507.Fn callout_stop
508and
509.Fn callout_drain
510functions return a value of one if the callout was removed by the
511function, or zero if the callout could not be stopped or was not running
512in the first place.
513.Sh HISTORY
514The original work on the data structures used in this implementation
515was published by
516.An G. Varghese
517and
518.An A. Lauck
519in the paper
520.%T "Hashed and Hierarchical Timing Wheels: Data Structures for the Efficient Implementation of a Timer Facility"
521in the
522.%B "Proceedings of the 11th ACM Annual Symposium on Operating Systems Principles" .
523The current implementation replaces the long standing
524.Bx
525linked list
526callout mechanism which offered O(n) insertion and removal running time
527but did not generate or require handles for untimeout operations.
528.Pp
529In
530.Dx
531the entire API was reformulated by Matthew Dillon for optimal SMP
532operation, uses much larger rings, and is capable of queuing one
533operation concurrent with an in-progress callback without blocking.
534