On Fri, Jul 22, 2022 at 01:38:16PM -0500, Scott Cheloha wrote: > Hi, > > As promised, here is the timeout.9 manpage rewrite I've been sitting > on. I am pretty sure jmc@ (and maybe schwarze@) read an earlier > version of this. It has drifted a bit since then, but not much.
No general mandoc issues or nits I can see, good. > My main goal here is to make all the "gotchas" in the timeout API more > explicit. The API is large, so the manpage is necessarily longer than > the average manpage. In this regard your diff reads good to me. > We're also stuck in the midst of an API transition, so there is some > overlap in the API coverage. Hopefully most of that redundancy can be > consolidated in the future after I finish the clock interrupt work. If by overlap you mean discrepancy between code and documentation, please avoid documenting nonexistent code; new manual bits should come with or after new code. See inline. Some functions exist in code but are not yet covered by this diff. This seems fine and can be done as next steps. Otherwise existing <kern/timeout.h> signatures match timeout.9 after you diff. > > -Scott > > Index: share/man/man9/timeout.9 > =================================================================== > RCS file: /cvs/src/share/man/man9/timeout.9,v > retrieving revision 1.55 > diff -u -p -r1.55 timeout.9 > --- share/man/man9/timeout.9 22 Jun 2022 14:10:49 -0000 1.55 > +++ share/man/man9/timeout.9 22 Jul 2022 18:34:14 -0000 > @@ -1,6 +1,7 @@ > .\" $OpenBSD: timeout.9,v 1.55 2022/06/22 14:10:49 visa Exp $ > .\" > .\" Copyright (c) 2000 Artur Grabowski <[email protected]> > +.\" Copyright (c) 2021, 2022 Scott Cheloha <[email protected]> > .\" All rights reserved. > .\" > .\" Redistribution and use in source and binary forms, with or without > @@ -36,6 +37,8 @@ > .Nm timeout_add_nsec , > .Nm timeout_add_usec , > .Nm timeout_add_tv , > +.Nm timeout_rel_nsec , > +.Nm timeout_abs_ts , These two functions don't exist at all yet. > .Nm timeout_del , > .Nm timeout_del_barrier , > .Nm timeout_barrier , > @@ -44,281 +47,375 @@ > .Nm timeout_triggered , > .Nm TIMEOUT_INITIALIZER , > .Nm TIMEOUT_INITIALIZER_FLAGS > -.Nd execute a function after a specified period of time > +.Nd execute a function in the future > .Sh SYNOPSIS > .In sys/types.h > .In sys/timeout.h > .Ft void > -.Fn timeout_set "struct timeout *to" "void (*fn)(void *)" "void *arg" > +.Fo timeout_set > +.Fa "struct timeout *to" > +.Fa "void (*fn)(void *)" > +.Fa "void *arg" > +.Fc > .Ft void > .Fo timeout_set_flags > .Fa "struct timeout *to" > .Fa "void (*fn)(void *)" > .Fa "void *arg" > +.Fa "int kclock" sys/kern/kern_timeout.c does not yet have this flag, so it should not yet be documented. timeout_set_klock() however exists with the signature you document here. > .Fa "int flags" > .Fc > .Ft void > -.Fn timeout_set_proc "struct timeout *to" "void (*fn)(void *)" "void *arg" > +.Fo timeout_set_proc > +.Fa "struct timeout *to" > +.Fa "void (*fn)(void *)" > +.Fa "void *arg" > +.Fc > .Ft int > -.Fn timeout_add "struct timeout *to" "int ticks" > +.Fo timeout_add > +.Fa "struct timeout *to" > +.Fa "int nticks" > +.Fc > .Ft int > -.Fn timeout_del "struct timeout *to" > +.Fo timeout_add_sec > +.Fa "struct timeout *to" > +.Fa "int secs" > +.Fc > .Ft int > -.Fn timeout_del_barrier "struct timeout *to" > -.Ft void > -.Fn timeout_barrier "struct timeout *to" > +.Fo timeout_add_msec > +.Fa "struct timeout *to" > +.Fa "int msecs" > +.Fc > .Ft int > -.Fn timeout_pending "struct timeout *to" > +.Fo timeout_add_usec > +.Fa "struct timeout *to" > +.Fa "int usecs" > +.Fc > .Ft int > -.Fn timeout_initialized "struct timeout *to" > +.Fo timeout_add_nsec > +.Fa "struct timeout *to" > +.Fa "int nsecs" > +.Fc > .Ft int > -.Fn timeout_triggered "struct timeout *to" > +.Fo timeout_add_tv > +.Fa "struct timeout *to" > +.Fa "struct timeval *tv" > +.Fc > .Ft int > -.Fn timeout_add_tv "struct timeout *to" "struct timeval *" > +.Fo timeout_rel_nsec > +.Fa "struct timeout *to" > +.Fa "uint64_t nsecs" > +.Fc > .Ft int > -.Fn timeout_add_sec "struct timeout *to" "int sec" > +.Fo timeout_abs_ts > +.Fa "struct timeout *to" > +.Fa "const struct timespec *abs" > +.Fc Again, these two functions don't exist at all yet. > .Ft int > -.Fn timeout_add_msec "struct timeout *to" "int msec" > +.Fo timeout_del > +.Fa "struct timeout *to" > +.Fc > +.Ft int > +.Fo timeout_del_barrier > +.Fa "struct timeout *to" > +.Fc > +.Ft void > +.Fo timeout_barrier > +.Fa "struct timeout *to" > +.Fc > +.Ft int > +.Fo timeout_pending > +.Fa "struct timeout *to" > +.Fc > .Ft int > -.Fn timeout_add_usec "struct timeout *to" "int usec" > +.Fo timeout_initialized > +.Fa "struct timeout *to" > +.Fc > .Ft int > -.Fn timeout_add_nsec "struct timeout *to" "int nsec" > -.Fn TIMEOUT_INITIALIZER "void (*fn)(void *)" "void *arg" > -.Fn TIMEOUT_INITIALIZER_FLAGS "void (*fn)(void *)" "void *arg" "int flags" > +.Fo timeout_triggered > +.Fa "struct timeout *to" > +.Fc > +.Fo TIMEOUT_INITIALIZER > +.Fa "void (*fn)(void *)" > +.Fa "void *arg" > +.Fc > +.Fo TIMEOUT_INITIALIZER_FLAGS > +.Fa "void (*fn)(void *)" > +.Fa "void *arg" > +.Fa "int kclock" The klock marco argument does not exist in <kern/timeout.h>. > +.Fa "int flags" > +.Fc > .Sh DESCRIPTION > The > .Nm timeout > -API provides a mechanism to execute a function at a given time. > -The granularity of the time is limited by the granularity of the > -.Xr hardclock 9 > -timer which executes > -.Xr hz 9 > -times a second. > +API provides a mechanism to schedule a function for asynchronous > +execution in the future. > .Pp > -It is the responsibility of the caller to provide these functions with > -pre-allocated timeout structures. > +All state is encapsulated in a caller-allocated timeout structure > +.Pq hereafter, a Qo timeout Qc . > +A timeout must be initialized before it may be used as input to other > +functions in the API. > .Pp > The > .Fn timeout_set > -function prepares the timeout structure > -.Fa to > -to be used in future calls to > -.Fn timeout_add > -and > -.Fn timeout_del . > -The timeout will be prepared to call the function specified by the > +function initializes the timeout > +.Fa to . > +When the timeout is executed, > +the function > .Fa fn > -argument with a > -.Fa void * > -argument given in the > +will be called with > .Fa arg > -argument. > -Once initialized, the > -.Fa to > -structure can be used repeatedly in > -.Fn timeout_add > -and > -.Fn timeout_del > -and does not need to be reinitialized unless > -the function called and/or its argument must change. > +as its first parameter. > +The timeout is implicitly scheduled against the > +.Dv KCLOCK_NONE > +clock and is not configured with any additional flags. > .Pp > The > .Fn timeout_set_flags > function is similar to > -.Fn timeout_set > -but it additionally accepts the bitwise OR of zero or more of the > -following > +.Fn timeout_set , > +except that it takes two additional parameters: > +.Bl -tag -width kclock > +.It Fa kclock See above, the kclock argument is for the existent but undocumented timeout_set_klock() and not timeout_set_flags(). > +The timeout is scheduled against the given > +.Fa kclock , > +which must be one of the following: > +.Bl -tag -width KCLOCK_UPTIME > +.It Dv KCLOCK_NONE > +Low resolution tick-based clock. > +The granularity of this clock is limited by the > +.Xr hardclock 9 , > +which executes roughly > +.Xr hz 9 > +times per second. > +.It Dv KCLOCK_UPTIME > +The uptime clock. > +Counts the time elapsed since the system booted. > +.El > +.It Fa flags > +The timeout's behavior may be configured with the bitwise OR of > +zero or more of the following > .Fa flags : > -.Bl -tag -width TIMEOUT_PROC -offset indent > +.Bl -tag -width TIMEOUT_PROC > .It Dv TIMEOUT_PROC > -Runs the timeout in a process context instead of the default > +Execute the timeout in a process context instead of the default > .Dv IPL_SOFTCLOCK > interrupt context. > .El > +.El > .Pp > The > .Fn timeout_set_proc > function is similar to > +.Fn timeout_set , > +except that the given timeout is configured with the > +.Dv TIMEOUT_PROC > +flag. > +.Pp > +A timeout may also be initialized statically. > +The > +.Fn TIMEOUT_INITIALIZER > +macro is equivalent to the > .Fn timeout_set > -but it runs the timeout in a process context instead of the default > -.Dv IPL_SOFTCLOCK > -interrupt context. > +function and the > +.Fn TIMEOUT_INITIALIZER_FLAGS > +macro is equivalent to the > +.Fn timeout_set_flags > +function. > .Pp > -The function > -.Fn timeout_add > -schedules the execution of the > -.Fa to > -timeout in at least > -.Fa ticks Ns /hz > +The interfaces available for scheduling a timeout vary with the > +.Fa kclock > +set during initialization. > +.Pp > +.Dv KCLOCK_NONE > +timeouts may be scheduled with the function > +.Fn timeout_add , > +which schedules the given timeout to execute after > +.Fa nticks > +.Xr hardclock 9 > +ticks have elapsed. > +In practice, > +.Fa nticks > +ticks will usually elapse in slightly less than > +.Pq Fa nticks Cm / Dv hz > seconds. > Negative values of > -.Fa ticks > +.Fa nticks > are illegal. > -If the value is > -.Sq 0 > -it will, in the current implementation, be treated as > -.Sq 1 , > -but in the future it might cause an immediate timeout. > -The timeout in the > -.Fa to > -argument must be already initialized by > -.Fn timeout_set , > -.Fn timeout_set_flags , > +If > +.Fa nticks > +is zero it will be silently rounded up to one. > +.Pp > +For convenience, > +.Dv KCLOCK_NONE > +timeouts may also be scheduled with > +.Fn timeout_add_sec , > +.Fn timeout_add_msec , > +.Fn timeout_add_usec , > +.Fn timeout_add_nsec , > or > -.Fn timeout_set_proc > -and may not be used in calls to > -.Fn timeout_set , > -.Fn timeout_set_flags , > +.Fn timeout_add_tv . > +These wrapper functions convert their input durations to a count of > +.Xr hardclock 9 > +ticks before calling > +.Fn timeout_add > +to schedule the given timeout. > +.Pp > +Timeouts for any other > +.Fa kclock > +may be scheduled with > +.Fn timeout_rel_nsec , > +which schedules the given timeout to execute after at least > +.Fa nsecs > +nanoseconds have elapsed on the timeout's > +.Fa kclock , > +or with > +.Fn timeout_abs_ts , > +which schedules the given timeout to execute at or after the absolute time > +.Fa abs > +has elapsed on the timeout's > +.Fa kclock . Again, these two functions don't exist at all yet. > +.Pp > +Once scheduled, > +a timeout is said to be > +.Qq pending . > +A pending timeout may not be reinitialized with > +.Fn timeout_set > or > -.Fn timeout_set_proc > -until it has timed out or been removed with > -.Fn timeout_del . > -If the timeout in the > -.Fa to > -argument is already scheduled, the old execution time will be > -replaced by the new one. > +.Fn timeout_set_flags > +until it has been executed or it has been cancelled with > +.Fn timeout_del > +or > +.Fn timeout_del_barrier . > +A pending timeout may be rescheduled without first cancelling it with > +.Fn timeout_del > +or > +.Fn timeout_del_barrier . > +The new expiration time will quietly supersede the original. > .Pp > The function > .Fn timeout_del > -will cancel the timeout in the argument > -.Fa to . > -If the timeout has already executed or has never been added, > +cancels any pending execution of the given timeout. > +If the timeout has already executed or was never scheduled, > the call will have no effect. > .Pp > +The > .Fn timeout_del_barrier > -is like > -.Fn timeout_del > -but it will wait until any current execution of the timeout has completed. > +function is similar to > +.Fn timeout_del , > +except that it may block until any current execution of the given timeout > +has completed. > .Pp > +The > .Fn timeout_barrier > -ensures that any current execution of the timeout in the argument > -.Fa to > -has completed before returning. > +function blocks until any current execution of the given timeout > +has completed. > .Pp > The caller of > .Fn timeout_barrier > or > .Fn timeout_del_barrier > must not hold locks that can block processing in the timeout's context. > -Otherwise, the system will deadlock. > +Otherwise, > +the system will deadlock. > .Pp > The > .Fn timeout_pending > -macro can be used to check if a timeout is scheduled to run. > +macro indicates whether the given timeout is scheduled for execution. > +A timeout's pending status is cleared when it executes or is cancelled. > .Pp > The > .Fn timeout_initialized > -macro can be used to check if a timeout has been initialized. > +macro indicates whether the given timeout has been initialized with > +.Fn timeout_set > +or > +.Fn timeout_set_flags . > +This macro must not be used unless the memory pointed to by > +.Fa to > +has been zeroed. > .Pp > The > .Fn timeout_triggered > -macro can be used to check if a timeout is running or has been run. > -The > -.Fn timeout_add > -and > -.Fn timeout_del > -functions clear the triggered state for that timeout. > -.Pp > -When possible, use the > -.Fn timeout_add_tv , > -.Fn timeout_add_sec , > -.Fn timeout_add_msec , > -.Fn timeout_add_usec , > -and > -.Fn timeout_add_nsec > -functions instead of > -.Fn timeout_add . > -Those functions add a timeout whilst converting the time specified > -by the respective types. > -They also defer the timeout handler for at least one tick if called > -with a positive value. > -.Pp > -A timeout declaration can be initialised with the > -.Fn TIMEOUT_INITIALIZER > -macro. > -The timeout will be prepared to call the function specified by the > -.Fa fn > -argument with the > -.Fa void * > -argument given in > -.Fa arg . > -.Pp > -The > -.Fn TIMEOUT_INITIALIZER_FLAGS > -macro is similar to > -.Fn TIMEOUT_INITIALIZER , > -but it accepts additional flags. > -See the > -.Fn timeout_set_flags > -function for details. > +macro indicates whether the given timeout is executing or has finished > +executing. > +Rescheduling or cancelling a timeout clears its triggered status. > .Sh CONTEXT > .Fn timeout_set , > .Fn timeout_set_flags , > and > .Fn timeout_set_proc > -can be called during autoconf, from process context, or from interrupt > -context. > +can be called during autoconf, > +from process context, > +or from interrupt context. > .Pp > .Fn timeout_add , > .Fn timeout_add_sec , > .Fn timeout_add_msec , > -.Fn timeout_add_nsec , > .Fn timeout_add_usec , > +.Fn timeout_add_nsec , > .Fn timeout_add_tv , > +.Fn timeout_rel_nsec , > +.Fn timeout_abs_ts , > .Fn timeout_del , > .Fn timeout_pending , > .Fn timeout_initialized , > +and > .Fn timeout_triggered > -can be called during autoconf, from process context, or from any > -interrupt context at or below > +may be called during autoconf, > +from process context, > +or from any interrupt context at or below > .Dv IPL_CLOCK . > .Pp > +The > .Fn timeout_barrier > and > .Fn timeout_del_barrier > -can be called from process context. > +functions may only be called from process context. > .Pp > -When the timeout runs, the > +When a timeout is executed, > +the function > .Fa fn > -argument to > -.Fn timeout_set > -or > -.Fn timeout_set_flags > -will be called in an interrupt context at > +given at initialization is called from the > .Dv IPL_SOFTCLOCK > -or a process context if the > +interrupt context, > +or a process context if the timeout was configured with the > .Dv TIMEOUT_PROC > -flag was given at initialization. > -The > +flag. > +The function > .Fa fn > -argument to > -.Fn timeout_set_proc > -will be called in a process context. > +must not block. > +.Pp > +Currently, > +all timeouts are executed under the kernel lock. > .Sh RETURN VALUES > .Fn timeout_add , > .Fn timeout_add_sec , > .Fn timeout_add_msec , > -.Fn timeout_add_nsec , > .Fn timeout_add_usec , > -and > +.Fn timeout_add_nsec , > .Fn timeout_add_tv > -will return 1 if the timeout > +.Fn timeout_rel_nsec , > +and > +.Fn timeout_abs_ts > +return 1 if the timeout > .Fa to > -was added to the timeout schedule or 0 if it was already queued. > +is newly scheduled or 0 if the timeout is already pending. > .Pp > .Fn timeout_del > and > .Fn timeout_del_barrier > -will return 1 if the timeout > +return 1 if the timeout > .Fa to > -was removed from the pending timeout schedule or 0 if it was not > -currently queued. > +is pending or 0 otherwise. > .Sh CODE REFERENCES > These functions are implemented in the file > .Pa sys/kern/kern_timeout.c . > .Sh SEE ALSO > +.Xr hardclock 9 , > .Xr hz 9 , > +.Xr microtime 9 , > .Xr splclock 9 , > +.Xr task_add 9 , > .Xr tsleep 9 , > .Xr tvtohz 9 > .Rs >
