summaryrefslogtreecommitdiff
path: root/static/freebsd/man9/callout.9 3.html
diff options
context:
space:
mode:
Diffstat (limited to 'static/freebsd/man9/callout.9 3.html')
-rw-r--r--static/freebsd/man9/callout.9 3.html614
1 files changed, 0 insertions, 614 deletions
diff --git a/static/freebsd/man9/callout.9 3.html b/static/freebsd/man9/callout.9 3.html
deleted file mode 100644
index e2951509..00000000
--- a/static/freebsd/man9/callout.9 3.html
+++ /dev/null
@@ -1,614 +0,0 @@
-<table class="head">
- <tr>
- <td class="head-ltitle">CALLOUT(9)</td>
- <td class="head-vol">Kernel Developer's Manual</td>
- <td class="head-rtitle">CALLOUT(9)</td>
- </tr>
-</table>
-<div class="manual-text">
-<section class="Sh">
-<h1 class="Sh" id="NAME"><a class="permalink" href="#NAME">NAME</a></h1>
-<p class="Pp"><code class="Nm">callout_active</code>,
- <code class="Nm">callout_deactivate</code>,
- <code class="Nm">callout_drain</code>, <code class="Nm">callout_init</code>,
- <code class="Nm">callout_init_mtx</code>,
- <code class="Nm">callout_init_rm</code>,
- <code class="Nm">callout_init_rw</code>,
- <code class="Nm">callout_pending</code>,
- <code class="Nm">callout_reset</code>,
- <code class="Nm">callout_reset_curcpu</code>,
- <code class="Nm">callout_reset_on</code>,
- <code class="Nm">callout_reset_sbt</code>,
- <code class="Nm">callout_reset_sbt_curcpu</code>,
- <code class="Nm">callout_reset_sbt_on</code>,
- <code class="Nm">callout_schedule</code>,
- <code class="Nm">callout_schedule_curcpu</code>,
- <code class="Nm">callout_schedule_on</code>,
- <code class="Nm">callout_schedule_sbt</code>,
- <code class="Nm">callout_schedule_sbt_curcpu</code>,
- <code class="Nm">callout_schedule_sbt_on</code>,
- <code class="Nm">callout_stop</code>, <code class="Nm">callout_when</code>
- &#x2014; <span class="Nd">execute a function after a specified length of
- time</span></p>
-</section>
-<section class="Sh">
-<h1 class="Sh" id="SYNOPSIS"><a class="permalink" href="#SYNOPSIS">SYNOPSIS</a></h1>
-<p class="Pp"><code class="In">#include
- &lt;<a class="In">sys/types.h</a>&gt;</code>
- <br/>
- <code class="In">#include &lt;<a class="In">sys/callout.h</a>&gt;</code></p>
-<div class="Bd Pp Li">
-<pre>typedef void callout_func_t (void *);</pre>
-</div>
-<br/>
-<var class="Ft">int</var>
-<br/>
-<code class="Fn">callout_active</code>(<var class="Fa" style="white-space: nowrap;">struct
- callout *c</var>);
-<p class="Pp"><var class="Ft">void</var>
- <br/>
- <code class="Fn">callout_deactivate</code>(<var class="Fa" style="white-space: nowrap;">struct
- callout *c</var>);</p>
-<p class="Pp"><var class="Ft">int</var>
- <br/>
- <code class="Fn">callout_drain</code>(<var class="Fa" style="white-space: nowrap;">struct
- callout *c</var>);</p>
-<p class="Pp"><var class="Ft">void</var>
- <br/>
- <code class="Fn">callout_init</code>(<var class="Fa" style="white-space: nowrap;">struct
- callout *c</var>, <var class="Fa" style="white-space: nowrap;">int
- mpsafe</var>);</p>
-<p class="Pp"><var class="Ft">void</var>
- <br/>
- <code class="Fn">callout_init_mtx</code>(<var class="Fa" style="white-space: nowrap;">struct
- callout *c</var>, <var class="Fa" style="white-space: nowrap;">struct mtx
- *mtx</var>, <var class="Fa" style="white-space: nowrap;">int
- flags</var>);</p>
-<p class="Pp"><var class="Ft">void</var>
- <br/>
- <code class="Fn">callout_init_rm</code>(<var class="Fa" style="white-space: nowrap;">struct
- callout *c</var>, <var class="Fa" style="white-space: nowrap;">struct rmlock
- *rm</var>, <var class="Fa" style="white-space: nowrap;">int
- flags</var>);</p>
-<p class="Pp"><var class="Ft">void</var>
- <br/>
- <code class="Fn">callout_init_rw</code>(<var class="Fa" style="white-space: nowrap;">struct
- callout *c</var>, <var class="Fa" style="white-space: nowrap;">struct rwlock
- *rw</var>, <var class="Fa" style="white-space: nowrap;">int
- flags</var>);</p>
-<p class="Pp"><var class="Ft">int</var>
- <br/>
- <code class="Fn">callout_pending</code>(<var class="Fa" style="white-space: nowrap;">struct
- callout *c</var>);</p>
-<p class="Pp"><var class="Ft">int</var>
- <br/>
- <code class="Fn">callout_reset</code>(<var class="Fa">struct callout *c</var>,
- <var class="Fa">int ticks</var>, <var class="Fa">callout_func_t *func</var>,
- <var class="Fa">void *arg</var>);</p>
-<p class="Pp"><var class="Ft">int</var>
- <br/>
- <code class="Fn">callout_reset_curcpu</code>(<var class="Fa">struct callout
- *c</var>, <var class="Fa">int ticks</var>, <var class="Fa">callout_func_t
- *func</var>, <var class="Fa">void *arg</var>);</p>
-<p class="Pp"><var class="Ft">int</var>
- <br/>
- <code class="Fn">callout_reset_on</code>(<var class="Fa">struct callout
- *c</var>, <var class="Fa">int ticks</var>, <var class="Fa">callout_func_t
- *func</var>, <var class="Fa">void *arg</var>, <var class="Fa">int
- cpu</var>);</p>
-<p class="Pp"><var class="Ft">int</var>
- <br/>
- <code class="Fn">callout_reset_sbt</code>(<var class="Fa">struct callout
- *c</var>, <var class="Fa">sbintime_t sbt</var>, <var class="Fa">sbintime_t
- pr</var>, <var class="Fa">callout_func_t *func</var>, <var class="Fa">void
- *arg</var>, <var class="Fa">int flags</var>);</p>
-<p class="Pp"><var class="Ft">int</var>
- <br/>
- <code class="Fn">callout_reset_sbt_curcpu</code>(<var class="Fa">struct
- callout *c</var>, <var class="Fa">sbintime_t sbt</var>,
- <var class="Fa">sbintime_t pr</var>, <var class="Fa">callout_func_t
- *func</var>, <var class="Fa">void *arg</var>, <var class="Fa">int
- flags</var>);</p>
-<p class="Pp"><var class="Ft">int</var>
- <br/>
- <code class="Fn">callout_reset_sbt_on</code>(<var class="Fa">struct callout
- *c</var>, <var class="Fa">sbintime_t sbt</var>, <var class="Fa">sbintime_t
- pr</var>, <var class="Fa">callout_func_t *func</var>, <var class="Fa">void
- *arg</var>, <var class="Fa">int cpu</var>, <var class="Fa">int
- flags</var>);</p>
-<p class="Pp"><var class="Ft">int</var>
- <br/>
- <code class="Fn">callout_schedule</code>(<var class="Fa" style="white-space: nowrap;">struct
- callout *c</var>, <var class="Fa" style="white-space: nowrap;">int
- ticks</var>);</p>
-<p class="Pp"><var class="Ft">int</var>
- <br/>
- <code class="Fn">callout_schedule_curcpu</code>(<var class="Fa" style="white-space: nowrap;">struct
- callout *c</var>, <var class="Fa" style="white-space: nowrap;">int
- ticks</var>);</p>
-<p class="Pp"><var class="Ft">int</var>
- <br/>
- <code class="Fn">callout_schedule_on</code>(<var class="Fa" style="white-space: nowrap;">struct
- callout *c</var>, <var class="Fa" style="white-space: nowrap;">int
- ticks</var>, <var class="Fa" style="white-space: nowrap;">int
- cpu</var>);</p>
-<p class="Pp"><var class="Ft">int</var>
- <br/>
- <code class="Fn">callout_schedule_sbt</code>(<var class="Fa">struct callout
- *c</var>, <var class="Fa">sbintime_t sbt</var>, <var class="Fa">sbintime_t
- pr</var>, <var class="Fa">int flags</var>);</p>
-<p class="Pp"><var class="Ft">int</var>
- <br/>
- <code class="Fn">callout_schedule_sbt_curcpu</code>(<var class="Fa">struct
- callout *c</var>, <var class="Fa">sbintime_t sbt</var>,
- <var class="Fa">sbintime_t pr</var>, <var class="Fa">int flags</var>);</p>
-<p class="Pp"><var class="Ft">int</var>
- <br/>
- <code class="Fn">callout_schedule_sbt_on</code>(<var class="Fa">struct callout
- *c</var>, <var class="Fa">sbintime_t sbt</var>, <var class="Fa">sbintime_t
- pr</var>, <var class="Fa">int cpu</var>, <var class="Fa">int
- flags</var>);</p>
-<p class="Pp"><var class="Ft">int</var>
- <br/>
- <code class="Fn">callout_stop</code>(<var class="Fa" style="white-space: nowrap;">struct
- callout *c</var>);</p>
-<p class="Pp"><var class="Ft">sbintime_t</var>
- <br/>
- <code class="Fn">callout_when</code>(<var class="Fa">sbintime_t sbt</var>,
- <var class="Fa">sbintime_t precision</var>, <var class="Fa">int flags</var>,
- <var class="Fa">sbintime_t *sbt_res</var>, <var class="Fa">sbintime_t
- *precision_res</var>);</p>
-</section>
-<section class="Sh">
-<h1 class="Sh" id="DESCRIPTION"><a class="permalink" href="#DESCRIPTION">DESCRIPTION</a></h1>
-<p class="Pp">The <code class="Nm">callout</code> 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 (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.</p>
-<p class="Pp">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.</p>
-<p class="Pp">Callout functions must not sleep. They may not acquire sleepable
- locks, wait on condition variables, perform blocking allocation requests, or
- invoke any other action that might sleep.</p>
-<p class="Pp" id="callout_init">Each callout structure must be initialized by
- <a class="permalink" href="#callout_init"><code class="Fn">callout_init</code></a>(),
- <code class="Fn">callout_init_mtx</code>(),
- <code class="Fn">callout_init_rm</code>(), or
- <code class="Fn">callout_init_rw</code>() before it is passed to any of the
- other callout functions. The <code class="Fn">callout_init</code>() function
- initializes a callout structure in <var class="Fa">c</var> that is not
- associated with a specific lock. If the <var class="Fa">mpsafe</var>
- argument is zero, the callout structure is not considered to be
- &#x201C;multi-processor safe&#x201D;; and the Giant lock will be acquired
- before calling the callout function and released when the callout function
- returns.</p>
-<p class="Pp" id="callout_init_mtx">The
- <a class="permalink" href="#callout_init_mtx"><code class="Fn">callout_init_mtx</code></a>(),
- <code class="Fn">callout_init_rm</code>(), and
- <a class="permalink" href="#callout_init_rw"><code class="Fn" id="callout_init_rw">callout_init_rw</code></a>()
- functions initialize a callout structure in <var class="Fa">c</var> that is
- associated with a specific lock. The lock is specified by the
- <var class="Fa">mtx</var>, <var class="Fa">rm</var>, or
- <var class="Fa">rw</var> parameter. The associated lock must be held while
- stopping or rescheduling the callout. The callout subsystem acquires the
- associated lock before calling the callout function and releases it after
- the function returns. If the callout was cancelled while the callout
- subsystem waited for the associated lock, the callout function is not
- called, and the associated lock is released. This ensures that stopping or
- rescheduling the callout will abort any previously scheduled invocation.</p>
-<p class="Pp" id="callout_init_rm">A sleepable read-mostly lock (one initialized
- with the <code class="Dv">RM_SLEEPABLE</code> flag) may not be used with
- <a class="permalink" href="#callout_init_rm"><code class="Fn">callout_init_rm</code></a>().
- Similarly, other sleepable lock types such as <a class="Xr">sx(9)</a> and
- <a class="Xr">lockmgr(9)</a> cannot be used with callouts because sleeping
- is not permitted in the callout subsystem.</p>
-<p class="Pp" id="callout_init_mtx~2">These <var class="Fa">flags</var> may be
- specified for
- <a class="permalink" href="#callout_init_mtx~2"><code class="Fn">callout_init_mtx</code></a>(),
- <code class="Fn">callout_init_rm</code>(), or
- <a class="permalink" href="#callout_init_rw~2"><code class="Fn" id="callout_init_rw~2">callout_init_rw</code></a>():</p>
-<dl class="Bl-tag">
- <dt id="CALLOUT_RETURNUNLOCKED"><a class="permalink" href="#CALLOUT_RETURNUNLOCKED"><code class="Dv">CALLOUT_RETURNUNLOCKED</code></a></dt>
- <dd>The callout function will release the associated lock itself, so the
- callout subsystem should not attempt to unlock it after the callout
- function returns.</dd>
- <dt id="CALLOUT_SHAREDLOCK"><a class="permalink" href="#CALLOUT_SHAREDLOCK"><code class="Dv">CALLOUT_SHAREDLOCK</code></a></dt>
- <dd>The lock is only acquired in read mode when running the callout handler.
- This flag is ignored by <code class="Fn">callout_init_mtx</code>().</dd>
-</dl>
-<p class="Pp" id="callout_stop">The function
- <a class="permalink" href="#callout_stop"><code class="Fn">callout_stop</code></a>()
- cancels a callout <var class="Fa">c</var> if it is currently pending. If the
- callout is pending and successfully stopped, then
- <code class="Fn">callout_stop</code>() returns a value of one. If the
- callout is not set, or has already been serviced, then negative one is
- returned. If the callout is currently being serviced and cannot be stopped,
- then zero will be returned. If the callout is currently being serviced and
- cannot be stopped, and at the same time a next invocation of the same
- callout is also scheduled, then <code class="Fn">callout_stop</code>()
- unschedules the next run and returns zero. If the callout has an associated
- lock, then that lock must be held when this function is called.</p>
-<p class="Pp" id="callout_drain">The function
- <a class="permalink" href="#callout_drain"><code class="Fn">callout_drain</code></a>()
- is identical to <code class="Fn">callout_stop</code>() except that it will
- wait for the callout <var class="Fa">c</var> 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 before <code class="Fn">callout_drain</code>()
- returns. However, the callout subsystem does guarantee that the callout will
- be fully stopped before <code class="Fn">callout_drain</code>() returns.</p>
-<p class="Pp" id="callout_reset">The
- <a class="permalink" href="#callout_reset"><code class="Fn">callout_reset</code></a>()
- and
- <a class="permalink" href="#callout_schedule"><code class="Fn" id="callout_schedule">callout_schedule</code></a>()
- function families schedule a future function invocation for callout
- <var class="Fa">c</var>. If <var class="Fa">c</var> already has a pending
- callout, it is cancelled before the new invocation is scheduled. These
- functions return a value of one 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.</p>
-<p class="Pp">The time at which the callout function will be invoked is
- determined by either the <var class="Fa">ticks</var> argument or the
- <var class="Fa">sbt</var>, <var class="Fa">pr</var>, and
- <var class="Fa">flags</var> arguments. When <var class="Fa">ticks</var> is
- used, the callout is scheduled to execute after
- <var class="Fa">ticks</var><span class="No">/hz</span> seconds. Non-positive
- values of <var class="Fa">ticks</var> are silently converted to the value
- &#x2018;1&#x2019;.</p>
-<p class="Pp">The <var class="Fa">sbt</var>, <var class="Fa">pr</var>, and
- <var class="Fa">flags</var> arguments provide more control over the
- scheduled time including support for higher resolution times, specifying the
- precision of the scheduled time, and setting an absolute deadline instead of
- a relative timeout. The callout is scheduled to execute in a time window
- which begins at the time specified in <var class="Fa">sbt</var> and extends
- for the amount of time specified in <var class="Fa">pr</var>. If
- <var class="Fa">sbt</var> specifies a time in the past, the window is
- adjusted to start at the current time. A non-zero value for
- <var class="Fa">pr</var> allows the callout subsystem to coalesce callouts
- scheduled close to each other into fewer timer interrupts, reducing
- processing overhead and power consumption. These <var class="Fa">flags</var>
- may be specified to adjust the interpretation of <var class="Fa">sbt</var>
- and <var class="Fa">pr</var>:</p>
-<dl class="Bl-tag">
- <dt id="C_ABSOLUTE"><a class="permalink" href="#C_ABSOLUTE"><code class="Dv">C_ABSOLUTE</code></a></dt>
- <dd>Handle the <var class="Fa">sbt</var> argument as an absolute time since
- boot. By default, <var class="Fa">sbt</var> is treated as a relative
- amount of time, similar to <var class="Fa">ticks</var>.</dd>
- <dt id="C_DIRECT_EXEC"><a class="permalink" href="#C_DIRECT_EXEC"><code class="Dv">C_DIRECT_EXEC</code></a></dt>
- <dd>Run the handler directly from hardware interrupt context instead of from
- the softclock thread. This reduces latency and overhead, but puts more
- constraints on the callout function. Callout functions run in this context
- may use only spin mutexes for locking and should be as small as possible
- because they run with absolute priority.</dd>
- <dt id="C_PREL"><a class="permalink" href="#C_PREL"><code class="Fn">C_PREL</code></a>()</dt>
- <dd>Specifies relative event time precision as binary logarithm of time
- interval divided by acceptable time deviation: 1 -- 1/2, 2 -- 1/4, etc.
- Note that the larger of <var class="Fa">pr</var> or this value is used as
- the length of the time window. Smaller values (which result in larger time
- intervals) allow the callout subsystem to aggregate more events in one
- timer interrupt.</dd>
- <dt id="C_PRECALC"><a class="permalink" href="#C_PRECALC"><code class="Dv">C_PRECALC</code></a></dt>
- <dd>The <var class="Fa">sbt</var> argument specifies the absolute time at
- which the callout should be run, and the <var class="Fa">pr</var> argument
- specifies the requested precision, which will not be adjusted during the
- scheduling process. The <var class="Fa">sbt</var> and
- <var class="Fa">pr</var> values should be calculated by an earlier call to
- <code class="Fn">callout_when</code>() which uses the user-supplied
- <var class="Fa">sbt</var>, <var class="Fa">pr</var>, and
- <var class="Fa">flags</var> values.</dd>
- <dt id="C_HARDCLOCK"><a class="permalink" href="#C_HARDCLOCK"><code class="Dv">C_HARDCLOCK</code></a></dt>
- <dd>Align the timeouts to
- <a class="permalink" href="#hardclock"><code class="Fn" id="hardclock">hardclock</code></a>()
- calls if possible.</dd>
-</dl>
-<p class="Pp" id="callout_reset~2">The
- <a class="permalink" href="#callout_reset~2"><code class="Fn">callout_reset</code></a>()
- functions accept a <var class="Fa">func</var> argument which identifies the
- function to be called when the time expires. It must be a pointer to a
- function that takes a single <var class="Fa">void *</var> argument. Upon
- invocation, <var class="Fa">func</var> will receive
- <var class="Fa">arg</var> as its only argument. The
- <a class="permalink" href="#callout_schedule~2"><code class="Fn" id="callout_schedule~2">callout_schedule</code></a>()
- functions reuse the <var class="Fa">func</var> and <var class="Fa">arg</var>
- arguments from the previous callout. Note that one of the
- <code class="Fn">callout_reset</code>() functions must always be called to
- initialize <var class="Fa">func</var> and <var class="Fa">arg</var> before
- one of the <code class="Fn">callout_schedule</code>() functions can be
- used.</p>
-<p class="Pp" id="callout_reset_on">The callout subsystem provides a softclock
- thread for each CPU in the system. Callouts are assigned to a single CPU and
- are executed by the softclock thread for that CPU. Initially, callouts are
- assigned to CPU 0. The
- <a class="permalink" href="#callout_reset_on"><code class="Fn">callout_reset_on</code></a>(),
- <a class="permalink" href="#callout_reset_sbt_on"><code class="Fn" id="callout_reset_sbt_on">callout_reset_sbt_on</code></a>(),
- <a class="permalink" href="#callout_schedule_on"><code class="Fn" id="callout_schedule_on">callout_schedule_on</code></a>()
- and
- <a class="permalink" href="#callout_schedule_sbt_on"><code class="Fn" id="callout_schedule_sbt_on">callout_schedule_sbt_on</code></a>()
- functions assign the callout to CPU <var class="Fa">cpu</var>. The
- <a class="permalink" href="#callout_reset_curcpu"><code class="Fn" id="callout_reset_curcpu">callout_reset_curcpu</code></a>(),
- <a class="permalink" href="#callout_reset_sbt_curpu"><code class="Fn" id="callout_reset_sbt_curpu">callout_reset_sbt_curpu</code></a>(),
- <a class="permalink" href="#callout_schedule_curcpu"><code class="Fn" id="callout_schedule_curcpu">callout_schedule_curcpu</code></a>()
- and
- <a class="permalink" href="#callout_schedule_sbt_curcpu"><code class="Fn" id="callout_schedule_sbt_curcpu">callout_schedule_sbt_curcpu</code></a>()
- functions assign the callout to the current CPU. The
- <code class="Fn">callout_reset</code>(),
- <a class="permalink" href="#callout_reset_sbt"><code class="Fn" id="callout_reset_sbt">callout_reset_sbt</code></a>(),
- <code class="Fn">callout_schedule</code>() and
- <a class="permalink" href="#callout_schedule_sbt"><code class="Fn" id="callout_schedule_sbt">callout_schedule_sbt</code></a>()
- functions schedule the callout to execute in the softclock thread of the CPU
- to which it is currently assigned.</p>
-<p class="Pp">Softclock threads are not pinned to their respective CPUs by
- default. The softclock thread for CPU 0 can be pinned to CPU 0 by setting
- the <var class="Va">kern.pin_default_swi</var> loader tunable to a non-zero
- value. Softclock threads for CPUs other than zero can be pinned to their
- respective CPUs by setting the <var class="Va">kern.pin_pcpu_swi</var>
- loader tunable to a non-zero value.</p>
-<p class="Pp" id="callout_pending">The macros
- <a class="permalink" href="#callout_pending"><code class="Fn">callout_pending</code></a>(),
- <code class="Fn">callout_active</code>() and
- <code class="Fn">callout_deactivate</code>() provide access to the current
- state of the callout. The <code class="Fn">callout_pending</code>() macro
- checks whether a callout is <i class="Em">pending</i>; a callout is
- considered <i class="Em">pending</i> 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,
- <code class="Fn">callout_pending</code>() will return
- <code class="Dv">FALSE</code> even though the callout function may not have
- finished (or even begun) executing. The
- <code class="Fn">callout_active</code>() macro checks whether a callout is
- marked as <i class="Em">active</i>, and the
- <code class="Fn">callout_deactivate</code>() macro clears the callout's
- <i class="Em">active</i> flag. The callout subsystem marks a callout as
- <i class="Em">active</i> when a timeout is set and it clears the
- <i class="Em">active</i> flag in <code class="Fn">callout_stop</code>() and
- <code class="Fn">callout_drain</code>(), but it
- <a class="permalink" href="#does"><i class="Em" id="does">does not</i></a>
- clear it when a callout expires normally via the execution of the callout
- function.</p>
-<p class="Pp" id="callout_when">The
- <a class="permalink" href="#callout_when"><code class="Fn">callout_when</code></a>()
- function may be used to pre-calculate the absolute time at which the timeout
- should be run and the precision of the scheduled run time according to the
- required time <var class="Fa">sbt</var>, precision
- <var class="Fa">precision</var>, and additional adjustments requested by the
- <var class="Fa">flags</var> argument. Flags accepted by the
- <code class="Fn">callout_when</code>() function are the same as flags for
- the <code class="Fn">callout_reset</code>() function. The resulting time is
- assigned to the variable pointed to by the <var class="Fa">sbt_res</var>
- argument, and the resulting precision is assigned to
- <var class="Fa">*precision_res</var>. When passing the results to
- <var class="Fa">callout_reset</var>, add the <var class="Va">C_PRECALC</var>
- flag to <var class="Fa">flags</var>, to avoid incorrect re-adjustment. The
- function is intended for situations where precise time of the callout run
- should be known in advance, since trying to read this time from the callout
- structure itself after a <code class="Fn">callout_reset</code>() call is
- racy.</p>
-<section class="Ss">
-<h2 class="Ss" id="Avoiding_Race_Conditions"><a class="permalink" href="#Avoiding_Race_Conditions">Avoiding
- Race Conditions</a></h2>
-<p class="Pp">The callout subsystem invokes callout functions from its own
- thread 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 lock as their first action, the callout function may
- have already been invoked, but is blocked waiting for that lock at the time
- that another thread tries to reset or stop the callout.</p>
-<p class="Pp">There are three main techniques for addressing these
- synchronization concerns. The first approach is preferred as it is the
- simplest:</p>
-<ol class="Bl-enum Bd-indent">
- <li id="callout_init_mtx~3">Callouts can be associated with a specific lock
- when they are initialized by
- <a class="permalink" href="#callout_init_mtx~3"><code class="Fn">callout_init_mtx</code></a>(),
- <code class="Fn">callout_init_rm</code>(), or
- <a class="permalink" href="#callout_init_rw~3"><code class="Fn" id="callout_init_rw~3">callout_init_rw</code></a>().
- When a callout is associated with a lock, the callout subsystem acquires
- the lock before the callout function is invoked. This allows the callout
- subsystem to transparently handle races between callout cancellation,
- scheduling, and execution. Note that the associated lock must be acquired
- before calling <code class="Fn">callout_stop</code>() or one of the
- <code class="Fn">callout_reset</code>() or
- <code class="Fn">callout_schedule</code>() functions to provide this
- safety.
- <p class="Pp" id="callout_init~2">A callout initialized via
- <a class="permalink" href="#callout_init~2"><code class="Fn">callout_init</code></a>()
- with <var class="Fa">mpsafe</var> set to zero is implicitly associated
- with the <var class="Va">Giant</var> mutex. If
- <var class="Va">Giant</var> is held when cancelling or rescheduling the
- callout, then its use will prevent races with the callout function.</p>
- </li>
- <li>The return value from <code class="Fn">callout_stop</code>() (or the
- <code class="Fn">callout_reset</code>() and
- <code class="Fn">callout_schedule</code>() function families) 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 <code class="Dv">FALSE</code> indicates that the callout function is
- about to be called. For example:
- <div class="Bd Pp Bd-indent Li">
- <pre>if (sc-&gt;sc_flags &amp; SCFLG_CALLOUT_RUNNING) {
- if (callout_stop(&amp;sc-&gt;sc_callout)) {
- sc-&gt;sc_flags &amp;= ~SCFLG_CALLOUT_RUNNING;
- /* successfully stopped */
- } else {
- /*
- * callout has expired and callout
- * function is about to be executed
- */
- }
-}</pre>
- </div>
- </li>
- <li>The <code class="Fn">callout_pending</code>(),
- <code class="Fn">callout_active</code>() and
- <code class="Fn">callout_deactivate</code>() 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 <i class="Em">active</i> and
- <i class="Em">pending</i>. When the timeout time arrives, the callout
- subsystem begins processing the callout by first clearing the
- <i class="Em">pending</i> flag. It then invokes the callout function
- without changing the <i class="Em">active</i> flag, and does not clear the
- <i class="Em">active</i> flag even after the callout function returns. The
- mechanism described here requires the callout function itself to clear the
- <i class="Em">active</i> flag using the
- <code class="Fn">callout_deactivate</code>() macro. The
- <code class="Fn">callout_stop</code>() and
- <code class="Fn">callout_drain</code>() functions always clear both the
- <i class="Em">active</i> and <i class="Em">pending</i> flags before
- returning.
- <p class="Pp" id="callout_pending~2">The callout function should first check
- the <i class="Em">pending</i> flag and return without action if
- <a class="permalink" href="#callout_pending~2"><code class="Fn">callout_pending</code></a>()
- returns <code class="Dv">TRUE</code>. This indicates that the callout
- was rescheduled using <code class="Fn">callout_reset</code>() just
- before the callout function was invoked. If
- <code class="Fn">callout_active</code>() returns
- <code class="Dv">FALSE</code> then the callout function should also
- return without action. This indicates that the callout has been stopped.
- Finally, the callout function should call
- <code class="Fn">callout_deactivate</code>() to clear the
- <i class="Em">active</i> flag. For example:</p>
- <div class="Bd Pp Bd-indent Li">
- <pre>mtx_lock(&amp;sc-&gt;sc_mtx);
-if (callout_pending(&amp;sc-&gt;sc_callout)) {
- /* callout was reset */
- mtx_unlock(&amp;sc-&gt;sc_mtx);
- return;
-}
-if (!callout_active(&amp;sc-&gt;sc_callout)) {
- /* callout was stopped */
- mtx_unlock(&amp;sc-&gt;sc_mtx);
- return;
-}
-callout_deactivate(&amp;sc-&gt;sc_callout);
-/* rest of callout function */</pre>
- </div>
- <p class="Pp" id="callout_stop~2">Together with appropriate synchronization,
- such as the mutex used above, this approach permits the
- <a class="permalink" href="#callout_stop~2"><code class="Fn">callout_stop</code></a>()
- and <code class="Fn">callout_reset</code>() functions to be used at any
- time without races. For example:</p>
- <div class="Bd Pp Bd-indent Li">
- <pre>mtx_lock(&amp;sc-&gt;sc_mtx);
-callout_stop(&amp;sc-&gt;sc_callout);
-/* The callout is effectively stopped now. */</pre>
- </div>
- <p class="Pp" id="callout_deactivate">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
- <a class="permalink" href="#callout_deactivate"><code class="Fn">callout_deactivate</code></a>()
- call.</p>
- <p class="Pp" id="callout_active">The above technique additionally ensures
- that the <i class="Em">active</i> flag always reflects whether the
- callout is effectively enabled or disabled. If
- <a class="permalink" href="#callout_active"><code class="Fn">callout_active</code></a>()
- 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.</p>
- </li>
-</ol>
-<p class="Pp" id="callout_drain~2">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
- <a class="permalink" href="#callout_drain~2"><code class="Fn">callout_drain</code></a>()
- should be used. In particular, a callout should always be drained prior to
- destroying its associated lock or releasing the storage for the callout
- structure.</p>
-</section>
-</section>
-<section class="Sh">
-<h1 class="Sh" id="RETURN_VALUES"><a class="permalink" href="#RETURN_VALUES">RETURN
- VALUES</a></h1>
-<p class="Pp">The <code class="Fn">callout_active</code>() macro returns the
- state of a callout's <i class="Em">active</i> flag.</p>
-<p class="Pp">The <code class="Fn">callout_pending</code>() macro returns the
- state of a callout's <i class="Em">pending</i> flag.</p>
-<p class="Pp">The <code class="Fn">callout_reset</code>() and
- <code class="Fn">callout_schedule</code>() function families return a value
- of one if the callout was pending before the new function invocation was
- scheduled.</p>
-<p class="Pp">The <code class="Fn">callout_stop</code>() and
- <code class="Fn">callout_drain</code>() functions return a value of one if
- the callout was still pending when it was called, a zero if the callout
- could not be stopped and a negative one is it was either not running or has
- already completed.</p>
-</section>
-<section class="Sh">
-<h1 class="Sh" id="SEE_ALSO"><a class="permalink" href="#SEE_ALSO">SEE
- ALSO</a></h1>
-<p class="Pp"><a class="Xr">dtrace_callout_execute(4)</a></p>
-</section>
-<section class="Sh">
-<h1 class="Sh" id="HISTORY"><a class="permalink" href="#HISTORY">HISTORY</a></h1>
-<p class="Pp"><span class="Ux">FreeBSD</span> initially used the long standing
- <span class="Ux">BSD</span> linked list callout mechanism which offered O(n)
- insertion and removal running time but did not generate or require handles
- for untimeout operations.</p>
-<p class="Pp"><span class="Ux">FreeBSD 3.0</span> introduced a new set of
- timeout and untimeout routines from <span class="Ux">NetBSD</span> based on
- the work of <span class="An">Adam M. Costello</span> and
- <span class="An">George Varghese</span>, published in a technical report
- entitled <span class="RsT">Redesigning the BSD Callout and Timer
- Facilities</span> and modified for inclusion in
- <span class="Ux">FreeBSD</span> by <span class="An">Justin T. Gibbs</span>.
- The original work on the data structures used in that implementation was
- published by <span class="An">G. Varghese</span> and <span class="An">A.
- Lauck</span> in the paper <span class="RsT">Hashed and Hierarchical Timing
- Wheels: Data Structures for the Efficient Implementation of a Timer
- Facility</span> in the <i class="RsB">Proceedings of the 11th ACM Annual
- Symposium on Operating Systems Principles.</i></p>
-<p class="Pp"><span class="Ux">FreeBSD 3.3</span> introduced the first
- implementations of <code class="Fn">callout_init</code>(),
- <code class="Fn">callout_reset</code>(), and
- <code class="Fn">callout_stop</code>() which permitted callers to allocate
- dedicated storage for callouts. This ensured that a callout would always
- fire unlike <code class="Fn">timeout</code>() which would silently fail if
- it was unable to allocate a callout.</p>
-<p class="Pp"><span class="Ux">FreeBSD 5.0</span> permitted callout handlers to
- be tagged as MPSAFE via <code class="Fn">callout_init</code>().</p>
-<p class="Pp"><span class="Ux">FreeBSD 5.3</span> introduced
- <code class="Fn">callout_drain</code>().</p>
-<p class="Pp"><span class="Ux">FreeBSD 6.0</span> introduced
- <code class="Fn">callout_init_mtx</code>().</p>
-<p class="Pp"><span class="Ux">FreeBSD 8.0</span> introduced per-CPU callout
- wheels, <code class="Fn">callout_init_rw</code>(), and
- <code class="Fn">callout_schedule</code>().</p>
-<p class="Pp"><span class="Ux">FreeBSD 9.0</span> changed the underlying timer
- interrupts used to drive callouts to prefer one-shot event timers instead of
- a periodic timer interrupt.</p>
-<p class="Pp"><span class="Ux">FreeBSD 10.0</span> switched the callout wheel to
- support tickless operation. These changes introduced
- <var class="Vt">sbintime_t</var> and the
- <code class="Fn">callout_reset_sbt*</code>() family of functions.
- <span class="Ux">FreeBSD 10.0</span> also added
- <code class="Dv">C_DIRECT_EXEC</code> and
- <code class="Fn">callout_init_rm</code>().</p>
-<p class="Pp"><span class="Ux">FreeBSD 10.2</span> introduced the
- <code class="Fn">callout_schedule_sbt*</code>() family of functions.</p>
-<p class="Pp"><span class="Ux">FreeBSD 11.0</span> introduced
- <code class="Fn">callout_async_drain</code>(). <span class="Ux">FreeBSD
- 11.1</span> introduced <code class="Fn">callout_when</code>().
- <span class="Ux">FreeBSD 13.0</span> removed
- <var class="Vt">timeout_t</var>, <code class="Fn">timeout</code>(), and
- <code class="Fn">untimeout</code>().</p>
-</section>
-</div>
-<table class="foot">
- <tr>
- <td class="foot-date">November 4, 2025</td>
- <td class="foot-os">FreeBSD 15.0</td>
- </tr>
-</table>