Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 24 Sep 2014 22:07:04 GMT
From:      John Baldwin <jhb@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 1200735 for review
Message-ID:  <201409242207.s8OM74Ss062346@skunkworks.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@1200735?ac=10

Change 1200735 by jhb@jhb_ralph on 2014/09/24 22:06:35

	Checkpoint WIP rewrite.

Affected files ...

.. //depot/projects/smpng/share/man/man9/timeout.9#12 edit

Differences ...

==== //depot/projects/smpng/share/man/man9/timeout.9#12 (text+ko) ====

@@ -33,27 +33,27 @@
 .Dt TIMEOUT 9
 .Os
 .Sh NAME
-.Nm timeout ,
-.Nm untimeout ,
+.Nm callout_active ,
+.Nm callout_deactivate ,
+.Nm callout_drain ,
 .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_pending ,
 .Nm callout_reset ,
+.Nm callout_reset_curcpu ,
 .Nm callout_reset_on ,
-.Nm callout_reset_curcpu ,
 .Nm callout_reset_sbt ,
+.Nm callout_reset_sbt_curcpu ,
 .Nm callout_reset_sbt_on ,
-.Nm callout_reset_sbt_curcpu ,
 .Nm callout_schedule ,
+.Nm callout_schedule_curcpu ,
 .Nm callout_schedule_on ,
-.Nm callout_schedule_curcpu ,
-.Nm callout_pending ,
-.Nm callout_active ,
-.Nm callout_deactivate
+.Nm callout_stop ,
+.Nm timeout ,
+.Nm untimeout
 .Nd execute a function after a specified length of time
 .Sh SYNOPSIS
 .In sys/types.h
@@ -61,16 +61,18 @@
 .Bd -literal
 typedef void timeout_t (void *);
 .Ed
-.Ft struct callout_handle
-.Fn timeout "timeout_t *func" "void *arg" "int ticks"
+.Ft int
+.Fn callout_active "struct callout *c"
+.Ft void
+.Fn callout_deactivate "struct callout *c"
+.Ft int
+.Fn callout_drain "struct callout *c"
 .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"
@@ -79,263 +81,255 @@
 .Ft void
 .Fn callout_init_rw "struct callout *c" "struct rwlock *rw" "int flags"
 .Ft int
-.Fn callout_stop "struct callout *c"
+.Fn callout_pending "struct callout *c"
 .Ft int
-.Fn callout_drain "struct callout *c"
+.Fn callout_reset "struct callout *c" "int ticks" "timeout_t *func" "void *arg"
 .Ft int
-.Fn callout_reset "struct callout *c" "int ticks" "timeout_t *func" "void *arg"
+.Fn callout_reset_curcpu "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 "struct callout *c" "sbintime_t sbt" \
+"sbintime_t pr" "timeout_t *func" "void *arg" "int flags"
+.Ft int
+.Fn callout_reset_sbt_curcpu "struct callout *c" "sbintime_t sbt" \
+"sbintime_t pr" "timeout_t *func" "void *arg" "int flags"
+.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"
+.Fn callout_schedule_on "struct callout *c" "int ticks" "int cpu"
 .Ft int
-.Fn callout_active "struct callout *c"
+.Fn callout_stop "struct callout *c"
+.Ft struct callout_handle
+.Fn timeout "timeout_t *func" "void *arg" "int ticks"
 .Ft void
-.Fn callout_deactivate "struct callout *c"
+.Fn untimeout "timeout_t *func" "void *arg" "struct callout_handle handle"
 .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.
+.Nm callout
+API is used to schedule a call to an arbitrary function at a specific
+time in the future.
+Consumers of this API are required to allocate a callout structure
+.Pq struct callout
+for each pending function invocation.
+This structure stores state about the pending function invocation including
+the function to be called and the time at which the function should be invoked.
+Pending function calls can be cancelled or rescheduled to a different time.
+In addition,
+a callout structure may be reused to schedule a new function call after a
+scheduled call is completed.
 .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.
+Callouts only provide a single-shot mode.
+If a consumer requires a periodic timer,
+it must explicitly reschedule each function call.
+This is normally done by rescheduling the subsequent call within the called
+function.
 .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.
+Callout functions are not permitted to sleep.
+They may not acquire any sleepable locks,
+wait on condition variables,
+perform blocking allocation requests,
+or invoke any other action which may sleep.
 .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
+Each callout structure must be initialized by
 .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
+or
+.Fn callout_init_rw
+before it is passed to any of the other callout functions.
+The
 .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.
+function initializes a callout structure in
+.Fa c
+that is not associated with a specific lock.
 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 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.
+.Fn callout_init_mtx ,
+.Fn callout_init_rm ,
+and
+.Fn callout_init_rw
+functions are initialize a callout structure in
+.Fa c that is associated with
+a specific lock.
+The lock is specified by the
+.Fa mtx ,
+.Fa rm ,
+or
+.Fa rw
+parameter, respectively.
+The callout subsystem acquires the associated lock before calling the
+callout function.
+The subsystem then checks if the pending callout has been cancelled
+while waiting for the associated lock.
+If it has,
+the callout function is not called and the associated lock is released.
+If it has not,
+the callout function is called and the associated lock is released by the
+subsystem after the callout function returns.
+In addition,
+the callout must only be cancelled or rescheduled while holding the
+associated lock.
+This guarantees that stopping or rescheduling a callout associated with a
+lock will not race with the callout function itself.
+.Pp
+Only regular mutexes may be used with
+.Fn callout_init_mtx ;
+spin mutexes are not supported.
+A sleepable read-mostly lock
+.Po
+one initialized with the
+.Dv RM_SLEEPABLE
+flag
+.Pc
+may not be used with
+.Fn callout_init_rm .
+Similarly, other sleepable lock types such as
+.Xr sx 9
+and
+.Xr lockmgr 9
+cannot be used with callouts because sleeping is not permitted in
+the callout subsystem.
+.Pp
 The following
 .Fa flags
-may be specified:
+may be specified for
+.Fn callout_init_mtx ,
+.Fn callout_init_rm ,
+or
+.Fn callout_init_rw :
 .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
+The callout function will release the associated lock 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 .
+This flag is ignored by
+.Fn callout_init_mtx .
 .El
 .Pp
 The function
 .Fn callout_stop
-cancels a callout if it is currently pending.
+cancels a callout
+.Fa c
+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.
+returns 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 lock,
+then that lock 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.
+except that it will wait for the callout
+.Fa c
+to complete 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 .
+callout, then the callout function may be invoked before
+.Fn callout_drain
+returns.
 However, the callout subsystem does guarantee that the callout will be
 fully stopped before
 .Fn callout_drain
 returns.
 .Pp
-The function
+The
 .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
+and
+.Fn callout_schedule
+function families schedule a future function invocation for callout
+.Fa c .
+If
+.Fa c
+already has a pending callout,
+it is cancelled before the new invocation is scheduled.
+These functions return a non-zero value if a pending callout was cancelled
+and zero if there was no pending callout.
+If the callout has an associated lock,
+then that lock must be held when any of these functions are called.
+.Pp
+The time at which the callout function will be invoked is determined by
+either the
+.Fa ticks
+argument or the
+.Fa sbt ,
+.Fa pr ,
+and
+.Fa flags
+arguments.
+When
+.Fa ticks
+is used,
+the callout is scheduled to execute after
+.Fa ticks Ns No /hz
+seconds.
+Non-positive values of
+.Fa ticks
+are silently converted to the value
+.Sq 1 .
+The
+.Fa sbr ,
+.Fa pr ,
+and
+.Fa flags
+arguments provide more control over the scheduled time including
+support for higher resolution times and setting an absolute deadline
+instead of a relative timeout.
+
+XXX sbt and pr
+
+.Pp
+The
 .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
+functions specify the function to be called when the time expires via the
+.Fa func
+argument.
+The
+.Fa arg
+value is passed to
+.Fn func
+as its sole argument when it is invoked.
+The
 .Fn callout_schedule
-(re)schedules an existing callout for a new period of time;
-it is equivalent to calling
-.Fn callout_reset
-with the
+functions reuse the
+.Fa func
+and
+.Fa arg
+arguments from the previous callout.
+Note that one of the
+.Fa callout_reset
+functions must always be called to initialize
 .Fa func
 and
 .Fa arg
-parameters extracted from the callout structure (though possibly with
-lower overhead).
+before one of the
+.Fn callout_schedule
+functions can be used.
+
+
 .Pp
 The functions
 .Fn callout_reset_on
@@ -346,6 +340,7 @@
 and
 .Fn callout_schedule
 but take an extra parameter specifying the target CPU for the callout.
+
 .Pp
 The function
 .Fn callout_reset_sbt_on
@@ -607,6 +602,99 @@
 To ensure that the callout is completely finished, a call to
 .Fn callout_drain
 should be used.
+.Sh LEGACY API
+.Bf Sy
+The functions below are a legacy API that will be removed in a future release.
+New code should not use these routines.
+.Ef
+.Pp
+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.
+.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.
+.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.
 .Sh RETURN VALUES
 The
 .Fn timeout



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201409242207.s8OM74Ss062346>