xref: /dragonfly/share/man/man9/callout.9 (revision 63e03116)
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 December 1, 2021
31.Dt TIMEOUT 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" "int mpsafe"
63.Ft void
64.Fn callout_init_lk "struct callout *c" "struct lock *lk"
65.Ft void
66.Fn callout_init_mp "struct callout *c"
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.  But generally
119speaking, callout functions should run in as short a time as possible
120as they can add lag to other unrelated callouts.
121.Pp
122Each callout structure must be initialized by
123.Fn callout_init ,
124.Fn callout_init_mp ,
125or
126.Fn callout_init_lk
127before it is passed to any of the other callout functions.
128The
129.Fn callout_init
130and
131.Fn callout_init_mp
132functions initialize a callout structure in
133.Fa c
134that is not associated with a specific lock.
135The former will hold the mp_lock across callback.  However, it is deprecated
136and should not be used in new code.
137.Fn callout_init_mp
138should be used for any new code.
139.Pp
140The
141.Fn callout_init_lk
142function initialize a callout structure in
143.Fa c
144that is associated with a specific lock.
145In
146.Fx
147the associated lock should be held while stopping or rescheduling the
148callout.
149In
150.Dx
151the same is true, but is not a requirement.
152.Pp
153The callout subsystem acquires the associated lock before calling the
154callout function and releases it after the function returns.
155If the callout was cancelled while the callout subsystem waited for the
156associated lock,
157the callout function is not called,
158and the associated lock is released.
159This ensures that stopping or rescheduling the callout will abort any
160previously scheduled invocation.
161.Pp
162The function
163.Fn callout_stop
164cancels a callout
165.Fa c
166if it is currently pending.
167If the callout is pending and successfully stopped, then
168.Fn callout_stop
169returns a value of one.
170In
171.Fx
172if the callout is not set, or
173has already been serviced, then
174negative one is returned.
175In
176.Dx
177if the callout is not set, or
178has already been serviced, then
179zero is returned.
180If the callout is currently being serviced and cannot be stopped,
181then zero will be returned.
182If the callout is currently being serviced and cannot be stopped, and at the
183same time a next invocation of the same callout is also scheduled, then
184.Fn callout_stop
185unschedules the next run and returns zero.
186In
187.Fx
188if the callout has an associated lock,
189then that lock must be held when this function is called.
190In
191.Dx
192if the callout has an associated lock,
193then that lock should be held when this function is called
194to avoid races, but does not have to be.
195.Pp
196In
197.Dx
198the stop operation is guaranteed to be synchronous if the callout
199was initialized with
200.Fn callout_init_lk .
201.Pp
202The function
203.Fn callout_stop_async
204is identical to
205.Fn callout_stop
206but does not block and allows the STOP operation to be asynchronous,
207meaning that the callout structure may still be relevant after the
208function returns.  This situation can occur if the callback was
209in-progress at the time the stop was issued.
210.Pp
211The function
212.Fn callout_cancel
213synchronously cancels a callout and returns a value similar to that
214of
215.Fn callout_stop .
216.Fn callout_cancel
217overrides all other operations while it is in-progress.
218.Pp
219The function
220.Fn callout_terminate
221synchronously cancels a callout and informs the system that the
222callout structure will no longer be referenced.  This function will
223clear the initialization flag and any further use of the callout structure
224will panic the system until it is next initialized.  The callout structure
225can be safely freed after this function returns, assuming other program
226references to it have been removed.
227.Pp
228The function
229.Fn callout_drain
230is identical to
231.Fn callout_stop
232except that it will wait for the callout
233.Fa c
234to complete if it is already in progress.
235This function MUST NOT be called while holding any
236locks on which the callout might block, or deadlock will result.
237Note that if the callout subsystem has already begun processing this
238callout, then the callout function may be invoked before
239.Fn callout_drain
240returns.
241However, the callout subsystem does guarantee that the callout will be
242fully stopped before
243.Fn callout_drain
244returns.
245.Pp
246The
247.Fn callout_reset
248function schedules a future function invocation for callout
249.Fa c .
250If
251.Fa c
252already has a pending callout,
253it is cancelled before the new invocation is scheduled.
254In
255.Fx
256these functions return a value of one if a pending callout was cancelled
257and zero if there was no pending callout.
258If the callout has an associated lock,
259then that lock must be held when any of these functions are called.
260In
261.Dx
262these functions return void.
263If the callout has an associated lock,
264then that lock should generally be held when any of these functions are
265called, but the API will work either way.
266If a callout is already in-progress, this function's parameters will be
267applied when the in-progress callback returns, if not overridden from
268within the callback.
269.Pp
270The time at which the callout function will be invoked is determined by
271the
272.Fa ticks
273argument.
274The callout is scheduled to execute after
275.Fa ticks Ns No /hz
276seconds.
277Non-positive values of
278.Fa ticks
279are silently converted to the value
280.Sq 1 .
281.Pp
282The
283.Fn callout_reset_bycpu
284function schedules the callout to occur on the target cpu.  The
285normal
286.Fn callout_reset
287function schedules the callout to occur on the current cpu.
288The
289.Fn callout_reset
290functions accept a
291.Fa func
292argument which identifies the function to be called when the time expires.
293It must be a pointer to a function that takes a single
294.Fa void *
295argument.
296Upon invocation,
297.Fa func
298will receive
299.Fa arg
300as its only argument.
301.Pp
302The callout subsystem provides a softclock thread for each CPU in the system.
303Callouts are assigned to a single CPU and are executed by the softclock thread
304for that CPU.
305The callouts are assigned to the current cpu or to a specific cpu
306depending on the call.
307.Pp
308The macros
309.Fn callout_pending ,
310.Fn callout_active
311and
312.Fn callout_deactivate
313provide access to the current state of the callout.
314The
315.Fn callout_pending
316macro checks whether a callout is
317.Em pending ;
318a callout is considered
319.Em pending
320when a timeout has been set but the time has not yet arrived.
321Note that once the timeout time arrives and the callout subsystem
322starts to process this callout,
323.Fn callout_pending
324will return
325.Dv FALSE
326even though the callout function may not have finished
327.Pq or even begun
328executing.
329The
330.Fn callout_active
331macro checks whether a callout is marked as
332.Em active ,
333and the
334.Fn callout_deactivate
335macro clears the callout's
336.Em active
337flag.
338The callout subsystem marks a callout as
339.Em active
340when a timeout is set and it clears the
341.Em active
342flag in
343.Fn callout_stop
344and
345.Fn callout_drain ,
346but it
347.Em does not
348clear it when a callout expires normally via the execution of the
349callout function.
350.Pp
351There are three main techniques for addressing these
352synchronization concerns.
353The first approach is preferred as it is the simplest:
354.Bl -enum -offset indent
355.It
356Callouts can be associated with a specific lock when they are initialized
357by
358.Fn callout_init_lk
359When a callout is associated with a lock,
360the callout subsystem acquires the lock before the callout function is
361invoked.
362This allows the callout subsystem to transparently handle races between
363callout cancellation,
364scheduling,
365and execution.
366Note that the associated lock must be acquired before calling
367.Fn callout_stop
368or
369.Fn callout_reset
370functions to provide this safety.
371.It
372The
373.Fn callout_pending ,
374.Fn callout_active
375and
376.Fn callout_deactivate
377macros can be used together to work around the race conditions,
378but the interpretation of these calls can be confusing and it
379is recommended that a different, caller-specific method be used to
380determine whether a race condition is present.
381.Pp
382When a callout's timeout is set, the callout subsystem marks the
383callout as both
384.Em active
385and
386.Em pending .
387When the timeout time arrives, the callout subsystem begins processing
388the callout by first clearing the
389.Em pending
390flag.
391It then invokes the callout function without changing the
392.Em active
393flag, and does not clear the
394.Em active
395flag even after the callout function returns.
396The mechanism described here requires the callout function itself to
397clear the
398.Em active
399flag using the
400.Fn callout_deactivate
401macro.
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
495macro returns the state of a callout's
496.Em active
497flag.
498.Pp
499The
500.Fn callout_pending
501macro returns the state of a callout's
502.Em pending
503flag.
504.Pp
505The
506.Fn callout_stop
507and
508.Fn callout_drain
509functions return a value of one if the callout was removed by the
510function, or zero if the callout could not be stopped or was not running
511in the first place.
512.Sh HISTORY
513The original work on the data structures used in this implementation
514was published by
515.An G. Varghese
516and
517.An A. Lauck
518in the paper
519.%T "Hashed and Hierarchical Timing Wheels: Data Structures for the Efficient Implementation of a Timer Facility"
520in the
521.%B "Proceedings of the 11th ACM Annual Symposium on Operating Systems Principles" .
522The current implementation replaces the long standing
523.Bx
524linked list
525callout mechanism which offered O(n) insertion and removal running time
526but did not generate or require handles for untimeout operations.
527.Pp
528In
529.Dx
530the entire API was reformulated by Matthew Dillon for optimal SMP
531operation, uses much larger rings, and is capable of queueing one
532operation concurrent with an in-progress callback without blocking.
533