summaryrefslogtreecommitdiffstats
path: root/share/man/man9/timeout.9
diff options
context:
space:
mode:
Diffstat (limited to 'share/man/man9/timeout.9')
-rw-r--r--share/man/man9/timeout.9642
1 files changed, 642 insertions, 0 deletions
diff --git a/share/man/man9/timeout.9 b/share/man/man9/timeout.9
new file mode 100644
index 0000000..178250c
--- /dev/null
+++ b/share/man/man9/timeout.9
@@ -0,0 +1,642 @@
+.\" $NetBSD: timeout.9,v 1.2 1996/06/23 22:32:34 pk Exp $
+.\"
+.\" Copyright (c) 1996 The NetBSD Foundation, Inc.
+.\" All rights reserved.
+.\"
+.\" This code is derived from software contributed to The NetBSD Foundation
+.\" by Paul Kranenburg.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd August 23, 2013
+.Dt TIMEOUT 9
+.Os
+.Sh NAME
+.Nm timeout ,
+.Nm untimeout ,
+.Nm callout_handle_init ,
+.Nm callout_init ,
+.Nm callout_init_mtx ,
+.Nm callout_init_rm ,
+.Nm callout_init_rw ,
+.Nm callout_stop ,
+.Nm callout_drain ,
+.Nm callout_reset ,
+.Nm callout_reset_on ,
+.Nm callout_reset_curcpu ,
+.Nm callout_reset_sbt ,
+.Nm callout_reset_sbt_on ,
+.Nm callout_reset_sbt_curcpu ,
+.Nm callout_schedule ,
+.Nm callout_schedule_on ,
+.Nm callout_schedule_curcpu ,
+.Nm callout_pending ,
+.Nm callout_active ,
+.Nm callout_deactivate
+.Nd execute a function after a specified length of time
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/systm.h
+.Bd -literal
+typedef void timeout_t (void *);
+.Ed
+.Ft struct callout_handle
+.Fn timeout "timeout_t *func" "void *arg" "int ticks"
+.Ft void
+.Fn callout_handle_init "struct callout_handle *handle"
+.Bd -literal
+struct callout_handle handle = CALLOUT_HANDLE_INITIALIZER(&handle);
+.Ed
+.Ft void
+.Fn untimeout "timeout_t *func" "void *arg" "struct callout_handle handle"
+.Ft void
+.Fn callout_init "struct callout *c" "int mpsafe"
+.Ft void
+.Fn callout_init_mtx "struct callout *c" "struct mtx *mtx" "int flags"
+.Fn void
+.Fn callout_init_rm "struct callout *c" "struct rmlock *rm" "int flags"
+.Ft void
+.Fn callout_init_rw "struct callout *c" "struct rwlock *rw" "int flags"
+.Ft int
+.Fn callout_stop "struct callout *c"
+.Ft int
+.Fn callout_drain "struct callout *c"
+.Ft int
+.Fn callout_reset "struct callout *c" "int ticks" "timeout_t *func" "void *arg"
+.Ft int
+.Fn callout_reset_on "struct callout *c" "int ticks" "timeout_t *func" \
+"void *arg" "int cpu"
+.Ft int
+.Fn callout_reset_sbt_on "struct callout *c" "sbintime_t sbt" \
+"sbintime_t pr" "timeout_t *func" "void *arg" "int cpu" "int flags"
+.Ft int
+.Fn callout_reset_curcpu "struct callout *c" "int ticks" "timeout_t *func" \
+"void *arg"
+.Ft int
+.Fn callout_schedule "struct callout *c" "int ticks"
+.Ft int
+.Fn callout_schedule_on "struct callout *c" "int ticks" "int cpu"
+.Ft int
+.Fn callout_schedule_curcpu "struct callout *c" "int ticks"
+.Ft int
+.Fn callout_pending "struct callout *c"
+.Ft int
+.Fn callout_active "struct callout *c"
+.Fn callout_deactivate "struct callout *c"
+.Sh DESCRIPTION
+The function
+.Fn timeout
+schedules a call to the function given by the argument
+.Fa func
+to take place after
+.Fa ticks Ns No /hz
+seconds.
+Non-positive values of
+.Fa ticks
+are silently converted to the value
+.Sq 1 .
+.Fa func
+should be a pointer to a function that takes a
+.Fa void *
+argument.
+Upon invocation,
+.Fa func
+will receive
+.Fa arg
+as its only argument.
+The return value from
+.Fn timeout
+is a
+.Ft struct callout_handle
+which can be used in conjunction with the
+.Fn untimeout
+function to request that a scheduled timeout be canceled.
+The
+.Fn timeout
+call is the old style and new code should use the
+.Fn callout_*
+functions.
+.Pp
+The function
+.Fn callout_handle_init
+can be used to initialize a handle to a state which will cause
+any calls to
+.Fn untimeout
+with that handle to return with no side
+effects.
+.Pp
+Assigning a callout handle the value of
+.Fn CALLOUT_HANDLE_INITIALIZER
+performs the same function as
+.Fn callout_handle_init
+and is provided for use on statically declared or global callout handles.
+.Pp
+The function
+.Fn untimeout
+cancels the timeout associated with
+.Fa handle
+using the
+.Fa func
+and
+.Fa arg
+arguments to validate the handle.
+If the handle does not correspond to a timeout with
+the function
+.Fa func
+taking the argument
+.Fa arg
+no action is taken.
+.Fa handle
+must be initialized by a previous call to
+.Fn timeout ,
+.Fn callout_handle_init ,
+or assigned the value of
+.Fn CALLOUT_HANDLE_INITIALIZER "&handle"
+before being passed to
+.Fn untimeout .
+The behavior of calling
+.Fn untimeout
+with an uninitialized handle
+is undefined.
+The
+.Fn untimeout
+call is the old style and new code should use the
+.Fn callout_*
+functions.
+.Pp
+As handles are recycled by the system, it is possible (although unlikely)
+that a handle from one invocation of
+.Fn timeout
+may match the handle of another invocation of
+.Fn timeout
+if both calls used the same function pointer and argument, and the first
+timeout is expired or canceled before the second call.
+The timeout facility offers O(1) running time for
+.Fn timeout
+and
+.Fn untimeout .
+Timeouts are executed from
+.Fn softclock
+with the
+.Va Giant
+lock held.
+Thus they are protected from re-entrancy.
+.Pp
+The functions
+.Fn callout_init ,
+.Fn callout_init_mtx ,
+.Fn callout_init_rm ,
+.Fn callout_init_rw ,
+.Fn callout_stop ,
+.Fn callout_drain ,
+.Fn callout_reset
+and
+.Fn callout_schedule
+are low-level routines for clients who wish to allocate their own
+callout structures.
+.Pp
+The function
+.Fn callout_init
+initializes a callout so it can be passed to
+.Fn callout_stop ,
+.Fn callout_drain ,
+.Fn callout_reset
+or
+.Fn callout_schedule
+without any side effects.
+If the
+.Fa mpsafe
+argument is zero,
+the callout structure is not considered to be
+.Dq multi-processor safe ;
+that is,
+the Giant lock will be acquired before calling the callout function,
+and released when the callout function returns.
+.Pp
+The
+.Fn callout_init_mtx
+function may be used as an alternative to
+.Fn callout_init .
+The parameter
+.Fa mtx
+specifies a mutex that is to be acquired by the callout subsystem
+before calling the callout function, and released when the callout
+function returns.
+The following
+.Fa flags
+may be specified:
+.Bl -tag -width ".Dv CALLOUT_RETURNUNLOCKED"
+.It Dv CALLOUT_RETURNUNLOCKED
+The callout function will release
+.Fa mtx
+itself, so the callout subsystem should not attempt to unlock it
+after the callout function returns.
+.El
+.Pp
+The
+.Fn callout_init_rw
+and the
+.Fn callout_init_rm
+fuctions serve the need of using rwlocks and rmlocks in conjunction
+with callouts.
+The functions do the same as
+.Fn callout_init
+with the possibility of specifying an extra
+.Fa rw
+or
+.Fa rm
+argument.
+If an
+.Fa rm
+argument is specified, the lock should be created without passing the
+.Dv RM_SLEEPABLE
+flag.
+The usable lock classes are currently limited to mutexes, rwlocks and
+non-sleepable rmlocks, because callout handlers run in softclock swi,
+so they cannot sleep nor acquire sleepable locks like sx or lockmgr.
+The following
+.Fa flags
+may be specified:
+.Bl -tag -width ".Dv CALLOUT_SHAREDLOCK"
+.It Dv CALLOUT_SHAREDLOCK
+The lock is only acquired in read mode when running the callout handler.
+It has no effects when used in conjunction with
+.Fa mtx .
+.El
+.Pp
+The function
+.Fn callout_stop
+cancels a callout if it is currently pending.
+If the callout is pending, then
+.Fn callout_stop
+will return a non-zero value.
+If the callout is not set, has already been serviced or is currently
+being serviced, then zero will be returned.
+If the callout has an associated mutex, then that mutex must be
+held when this function is called.
+.Pp
+The function
+.Fn callout_drain
+is identical to
+.Fn callout_stop
+except that it will wait for the callout to be completed if it is
+already in progress.
+This function MUST NOT be called while holding any
+locks on which the callout might block, or deadlock will result.
+Note that if the callout subsystem has already begun processing this
+callout, then the callout function may be invoked during the execution of
+.Fn callout_drain .
+However, the callout subsystem does guarantee that the callout will be
+fully stopped before
+.Fn callout_drain
+returns.
+.Pp
+The function
+.Fn callout_reset
+first performs the equivalent of
+.Fn callout_stop
+to disestablish the callout, and then establishes a new callout in the
+same manner as
+.Fn timeout .
+If there was already a pending callout and it was rescheduled, then
+.Fn callout_reset
+will return a non-zero value.
+If the callout has an associated mutex, then that mutex must be
+held when this function is called.
+The function
+.Fn callout_schedule
+(re)schedules an existing callout for a new period of time;
+it is equivalent to calling
+.Fn callout_reset
+with the
+.Fa func
+and
+.Fa arg
+parameters extracted from the callout structure (though possibly with
+lower overhead).
+.Pp
+The functions
+.Fn callout_reset_on
+and
+.Fn callout_schedule_on
+are equivalent to
+.Fn callout_reset
+and
+.Fn callout_schedule
+but take an extra parameter specifying the target CPU for the callout.
+.Pp
+The function
+.Fn callout_reset_sbt_on
+allows to get higher time resolution, taking relative or absolute time
+and precision instead of relative ticks count.
+If specified time is in past, it will be silently converted to present
+to run handler as soon as possible.
+.Pp
+The following
+.Fa flags
+may be specified:
+.Bl -tag -width ".Dv C_DIRECT_EXEC"
+.It Dv C_ABSOLUTE
+Handle the
+.Fa sbt
+argument as absolute time of the event since boot, or relative time otherwise.
+.It Dv C_DIRECT_EXEC
+Run handler directly from hardware interrupt context instead of softclock swi.
+It is faster, but puts more constraints on handlers.
+Handlers may use only spin mutexes for locking, and they must be fast because
+they run with absolute priority.
+.It Fn C_PREL
+Specifies relative event time precision as binary logarithm of time interval
+divided by acceptable time deviation: 1 -- 1/2, 2 -- 1/4, etc.
+Smaller value allows to aggregate more events in one timer interrupt to
+reduce processing overhead and power consumption.
+.El
+.Pp
+The functions
+.Fn callout_reset_curcpu
+and
+.Fn callout_schedule_curcpu
+are wrappers for
+.Fn callout_reset_on
+and
+.Fn callout_schedule_on
+using the current CPU as the target CPU.
+.Pp
+The macros
+.Fn callout_pending ,
+.Fn callout_active
+and
+.Fn callout_deactivate
+provide access to the current state of the callout.
+Careful use of these macros can avoid many of the race conditions
+that are inherent in asynchronous timer facilities; see
+.Sx "Avoiding Race Conditions"
+below for further details.
+The
+.Fn callout_pending
+macro checks whether a callout is
+.Em pending ;
+a callout is considered
+.Em pending
+when a timeout has been set but the time has not yet arrived.
+Note that once the timeout time arrives and the callout subsystem
+starts to process this callout,
+.Fn callout_pending
+will return
+.Dv FALSE
+even though the callout function may not have finished (or even begun)
+executing.
+The
+.Fn callout_active
+macro checks whether a callout is marked as
+.Em active ,
+and the
+.Fn callout_deactivate
+macro clears the callout's
+.Em active
+flag.
+The callout subsystem marks a callout as
+.Em active
+when a timeout is set and it clears the
+.Em active
+flag in
+.Fn callout_stop
+and
+.Fn callout_drain ,
+but it
+.Em does not
+clear it when a callout expires normally via the execution of the
+callout function.
+.Ss "Avoiding Race Conditions"
+The callout subsystem invokes callout functions from its own timer
+context.
+Without some kind of synchronization it is possible that a callout
+function will be invoked concurrently with an attempt to stop or reset
+the callout by another thread.
+In particular, since callout functions typically acquire a mutex as
+their first action, the callout function may have already been invoked,
+but be blocked waiting for that mutex at the time that another thread
+tries to reset or stop the callout.
+.Pp
+The callout subsystem provides a number of mechanisms to address these
+synchronization concerns:
+.Bl -enum -offset indent
+.It
+If the callout has an associated mutex that was specified using the
+.Fn callout_init_mtx
+function (or implicitly specified as the
+.Va Giant
+mutex using
+.Fn callout_init
+with
+.Fa mpsafe
+set to
+.Dv FALSE ) ,
+then this mutex is used to avoid the race conditions.
+The associated mutex must be acquired by the caller before calling
+.Fn callout_stop
+or
+.Fn callout_reset
+and it is guaranteed that the callout will be correctly stopped
+or reset as expected.
+Note that it is still necessary to use
+.Fn callout_drain
+before destroying the callout or its associated mutex.
+.It
+The return value from
+.Fn callout_stop
+and
+.Fn callout_reset
+indicates whether or not the callout was removed.
+If it is known that the callout was set and the callout function has
+not yet executed, then a return value of
+.Dv FALSE
+indicates that the callout function is about to be called.
+For example:
+.Bd -literal -offset indent
+if (sc->sc_flags & SCFLG_CALLOUT_RUNNING) {
+ if (callout_stop(&sc->sc_callout)) {
+ sc->sc_flags &= ~SCFLG_CALLOUT_RUNNING;
+ /* successfully stopped */
+ } else {
+ /*
+ * callout has expired and callout
+ * function is about to be executed
+ */
+ }
+}
+.Ed
+.It
+The
+.Fn callout_pending ,
+.Fn callout_active
+and
+.Fn callout_deactivate
+macros can be used together to work around the race conditions.
+When a callout's timeout is set, the callout subsystem marks the
+callout as both
+.Em active
+and
+.Em pending .
+When the timeout time arrives, the callout subsystem begins processing
+the callout by first clearing the
+.Em pending
+flag.
+It then invokes the callout function without changing the
+.Em active
+flag, and does not clear the
+.Em active
+flag even after the callout function returns.
+The mechanism described here requires the callout function itself to
+clear the
+.Em active
+flag using the
+.Fn callout_deactivate
+macro.
+The
+.Fn callout_stop
+and
+.Fn callout_drain
+functions always clear both the
+.Em active
+and
+.Em pending
+flags before returning.
+.Pp
+The callout function should first check the
+.Em pending
+flag and return without action if
+.Fn callout_pending
+returns
+.Dv TRUE .
+This indicates that the callout was rescheduled using
+.Fn callout_reset
+just before the callout function was invoked.
+If
+.Fn callout_active
+returns
+.Dv FALSE
+then the callout function should also return without action.
+This indicates that the callout has been stopped.
+Finally, the callout function should call
+.Fn callout_deactivate
+to clear the
+.Em active
+flag.
+For example:
+.Bd -literal -offset indent
+mtx_lock(&sc->sc_mtx);
+if (callout_pending(&sc->sc_callout)) {
+ /* callout was reset */
+ mtx_unlock(&sc->sc_mtx);
+ return;
+}
+if (!callout_active(&sc->sc_callout)) {
+ /* callout was stopped */
+ mtx_unlock(&sc->sc_mtx);
+ return;
+}
+callout_deactivate(&sc->sc_callout);
+/* rest of callout function */
+.Ed
+.Pp
+Together with appropriate synchronization, such as the mutex used above,
+this approach permits the
+.Fn callout_stop
+and
+.Fn callout_reset
+functions to be used at any time without races.
+For example:
+.Bd -literal -offset indent
+mtx_lock(&sc->sc_mtx);
+callout_stop(&sc->sc_callout);
+/* The callout is effectively stopped now. */
+.Ed
+.Pp
+If the callout is still pending then these functions operate normally,
+but if processing of the callout has already begun then the tests in
+the callout function cause it to return without further action.
+Synchronization between the callout function and other code ensures that
+stopping or resetting the callout will never be attempted while the
+callout function is past the
+.Fn callout_deactivate
+call.
+.Pp
+The above technique additionally ensures that the
+.Em active
+flag always reflects whether the callout is effectively enabled or
+disabled.
+If
+.Fn callout_active
+returns false, then the callout is effectively disabled, since even if
+the callout subsystem is actually just about to invoke the callout
+function, the callout function will return without action.
+.El
+.Pp
+There is one final race condition that must be considered when a
+callout is being stopped for the last time.
+In this case it may not be safe to let the callout function itself
+detect that the callout was stopped, since it may need to access
+data objects that have already been destroyed or recycled.
+To ensure that the callout is completely finished, a call to
+.Fn callout_drain
+should be used.
+.Sh RETURN VALUES
+The
+.Fn timeout
+function returns a
+.Ft struct callout_handle
+that can be passed to
+.Fn untimeout .
+The
+.Fn callout_stop
+and
+.Fn callout_drain
+functions return non-zero if the callout was still pending when it was
+called or zero otherwise.
+.Sh HISTORY
+The current timeout and untimeout routines are based on the work of
+.An Adam M. Costello
+and
+.An George Varghese ,
+published in a technical report entitled
+.%T "Redesigning the BSD Callout and Timer Facilities"
+and modified slightly for inclusion in
+.Fx
+by
+.An Justin T. Gibbs .
+The original work on the data structures used in this implementation
+was published by
+.An G. Varghese
+and
+.An A. Lauck
+in the paper
+.%T "Hashed and Hierarchical Timing Wheels: Data Structures for the Efficient Implementation of a Timer Facility"
+in the
+.%B "Proceedings of the 11th ACM Annual Symposium on Operating Systems Principles" .
+The current implementation replaces the long standing
+.Bx
+linked list
+callout mechanism which offered O(n) insertion and removal running time
+but did not generate or require handles for untimeout operations.
OpenPOWER on IntegriCloud