summaryrefslogtreecommitdiff
path: root/static/freebsd/man9/taskqueue.9 4.html
diff options
context:
space:
mode:
Diffstat (limited to 'static/freebsd/man9/taskqueue.9 4.html')
-rw-r--r--static/freebsd/man9/taskqueue.9 4.html494
1 files changed, 0 insertions, 494 deletions
diff --git a/static/freebsd/man9/taskqueue.9 4.html b/static/freebsd/man9/taskqueue.9 4.html
deleted file mode 100644
index d9c314ee..00000000
--- a/static/freebsd/man9/taskqueue.9 4.html
+++ /dev/null
@@ -1,494 +0,0 @@
-<table class="head">
- <tr>
- <td class="head-ltitle">TASKQUEUE(9)</td>
- <td class="head-vol">Kernel Developer's Manual</td>
- <td class="head-rtitle">TASKQUEUE(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">taskqueue</code> &#x2014;
- <span class="Nd">asynchronous task execution</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/param.h</a>&gt;</code>
- <br/>
- <code class="In">#include &lt;<a class="In">sys/kernel.h</a>&gt;</code>
- <br/>
- <code class="In">#include &lt;<a class="In">sys/malloc.h</a>&gt;</code>
- <br/>
- <code class="In">#include &lt;<a class="In">sys/queue.h</a>&gt;</code>
- <br/>
- <code class="In">#include &lt;<a class="In">sys/taskqueue.h</a>&gt;</code></p>
-<div class="Bd Pp Li">
-<pre>typedef void (*task_fn_t)(void *context, int pending);
-
-typedef void (*taskqueue_enqueue_fn)(void *context);
-
-struct task {
- STAILQ_ENTRY(task) ta_link; /* link for queue */
- u_short ta_pending; /* count times queued */
- u_short ta_priority; /* priority of task in queue */
- task_fn_t ta_func; /* task handler */
- void *ta_context; /* argument for handler */
-};
-
-enum taskqueue_callback_type {
- TASKQUEUE_CALLBACK_TYPE_INIT,
- TASKQUEUE_CALLBACK_TYPE_SHUTDOWN,
-};
-
-typedef void (*taskqueue_callback_fn)(void *context);
-
-struct timeout_task;</pre>
-</div>
-<br/>
-<var class="Ft">struct taskqueue *</var>
-<br/>
-<code class="Fn">taskqueue_create</code>(<var class="Fa" style="white-space: nowrap;">const
- char *name</var>, <var class="Fa" style="white-space: nowrap;">int
- mflags</var>,
- <var class="Fa" style="white-space: nowrap;">taskqueue_enqueue_fn
- enqueue</var>, <var class="Fa" style="white-space: nowrap;">void
- *context</var>);
-<p class="Pp"><var class="Ft">struct taskqueue *</var>
- <br/>
- <code class="Fn">taskqueue_create_fast</code>(<var class="Fa" style="white-space: nowrap;">const
- char *name</var>, <var class="Fa" style="white-space: nowrap;">int
- mflags</var>,
- <var class="Fa" style="white-space: nowrap;">taskqueue_enqueue_fn
- enqueue</var>, <var class="Fa" style="white-space: nowrap;">void
- *context</var>);</p>
-<p class="Pp"><var class="Ft">int</var>
- <br/>
- <code class="Fn">taskqueue_start_threads</code>(<var class="Fa" style="white-space: nowrap;">struct
- taskqueue **tqp</var>, <var class="Fa" style="white-space: nowrap;">int
- count</var>, <var class="Fa" style="white-space: nowrap;">int pri</var>,
- <var class="Fa" style="white-space: nowrap;">const char *name</var>,
- <var class="Fa" style="white-space: nowrap;">...</var>);</p>
-<p class="Pp"><var class="Ft">int</var>
- <br/>
- <code class="Fn">taskqueue_start_threads_cpuset</code>(<var class="Fa">struct
- taskqueue **tqp</var>, <var class="Fa">int count</var>, <var class="Fa">int
- pri</var>, <var class="Fa">cpuset_t *mask</var>, <var class="Fa">const char
- *name</var>, <var class="Fa">...</var>);</p>
-<p class="Pp"><var class="Ft">int</var>
- <br/>
- <code class="Fn">taskqueue_start_threads_in_proc</code>(<var class="Fa">struct
- taskqueue **tqp</var>, <var class="Fa">int count</var>, <var class="Fa">int
- pri</var>, <var class="Fa">struct proc *proc</var>, <var class="Fa">const
- char *name</var>, <var class="Fa">...</var>);</p>
-<p class="Pp"><var class="Ft">void</var>
- <br/>
- <code class="Fn">taskqueue_set_callback</code>(<var class="Fa" style="white-space: nowrap;">struct
- taskqueue *queue</var>, <var class="Fa" style="white-space: nowrap;">enum
- taskqueue_callback_type cb_type</var>,
- <var class="Fa" style="white-space: nowrap;">taskqueue_callback_fn
- callback</var>, <var class="Fa" style="white-space: nowrap;">void
- *context</var>);</p>
-<p class="Pp"><var class="Ft">void</var>
- <br/>
- <code class="Fn">taskqueue_free</code>(<var class="Fa" style="white-space: nowrap;">struct
- taskqueue *queue</var>);</p>
-<p class="Pp"><var class="Ft">int</var>
- <br/>
- <code class="Fn">taskqueue_enqueue</code>(<var class="Fa" style="white-space: nowrap;">struct
- taskqueue *queue</var>, <var class="Fa" style="white-space: nowrap;">struct
- task *task</var>);</p>
-<p class="Pp"><var class="Ft">int</var>
- <br/>
- <code class="Fn">taskqueue_enqueue_flags</code>(<var class="Fa" style="white-space: nowrap;">struct
- taskqueue *queue</var>, <var class="Fa" style="white-space: nowrap;">struct
- task *task</var>, <var class="Fa" style="white-space: nowrap;">int
- flags</var>);</p>
-<p class="Pp"><var class="Ft">int</var>
- <br/>
- <code class="Fn">taskqueue_enqueue_timeout</code>(<var class="Fa" style="white-space: nowrap;">struct
- taskqueue *queue</var>, <var class="Fa" style="white-space: nowrap;">struct
- timeout_task *timeout_task</var>,
- <var class="Fa" style="white-space: nowrap;">int ticks</var>);</p>
-<p class="Pp"><var class="Ft">int</var>
- <br/>
- <code class="Fn">taskqueue_enqueue_timeout_sbt</code>(<var class="Fa" style="white-space: nowrap;">struct
- taskqueue *queue</var>, <var class="Fa" style="white-space: nowrap;">struct
- timeout_task *timeout_task</var>,
- <var class="Fa" style="white-space: nowrap;">sbintime_t sbt</var>,
- <var class="Fa" style="white-space: nowrap;">sbintime_t pr</var>,
- <var class="Fa" style="white-space: nowrap;">int flags</var>);</p>
-<p class="Pp"><var class="Ft">int</var>
- <br/>
- <code class="Fn">taskqueue_cancel</code>(<var class="Fa" style="white-space: nowrap;">struct
- taskqueue *queue</var>, <var class="Fa" style="white-space: nowrap;">struct
- task *task</var>, <var class="Fa" style="white-space: nowrap;">u_int
- *pendp</var>);</p>
-<p class="Pp"><var class="Ft">int</var>
- <br/>
- <code class="Fn">taskqueue_cancel_timeout</code>(<var class="Fa" style="white-space: nowrap;">struct
- taskqueue *queue</var>, <var class="Fa" style="white-space: nowrap;">struct
- timeout_task *timeout_task</var>,
- <var class="Fa" style="white-space: nowrap;">u_int *pendp</var>);</p>
-<p class="Pp"><var class="Ft">void</var>
- <br/>
- <code class="Fn">taskqueue_drain</code>(<var class="Fa" style="white-space: nowrap;">struct
- taskqueue *queue</var>, <var class="Fa" style="white-space: nowrap;">struct
- task *task</var>);</p>
-<p class="Pp"><var class="Ft">void</var>
- <br/>
- <code class="Fn">taskqueue_drain_timeout</code>(<var class="Fa" style="white-space: nowrap;">struct
- taskqueue *queue</var>, <var class="Fa" style="white-space: nowrap;">struct
- timeout_task *timeout_task</var>);</p>
-<p class="Pp"><var class="Ft">void</var>
- <br/>
- <code class="Fn">taskqueue_drain_all</code>(<var class="Fa" style="white-space: nowrap;">struct
- taskqueue *queue</var>);</p>
-<p class="Pp"><var class="Ft">void</var>
- <br/>
- <code class="Fn">taskqueue_quiesce</code>(<var class="Fa" style="white-space: nowrap;">struct
- taskqueue *queue</var>);</p>
-<p class="Pp"><var class="Ft">void</var>
- <br/>
- <code class="Fn">taskqueue_block</code>(<var class="Fa" style="white-space: nowrap;">struct
- taskqueue *queue</var>);</p>
-<p class="Pp"><var class="Ft">void</var>
- <br/>
- <code class="Fn">taskqueue_unblock</code>(<var class="Fa" style="white-space: nowrap;">struct
- taskqueue *queue</var>);</p>
-<p class="Pp"><var class="Ft">int</var>
- <br/>
- <code class="Fn">taskqueue_member</code>(<var class="Fa" style="white-space: nowrap;">struct
- taskqueue *queue</var>, <var class="Fa" style="white-space: nowrap;">struct
- thread *td</var>);</p>
-<p class="Pp"><var class="Ft">void</var>
- <br/>
- <code class="Fn">taskqueue_run</code>(<var class="Fa" style="white-space: nowrap;">struct
- taskqueue *queue</var>);</p>
-<p class="Pp"><code class="Fn">TASK_INIT</code>(<var class="Fa" style="white-space: nowrap;">struct
- task *task</var>, <var class="Fa" style="white-space: nowrap;">int
- priority</var>, <var class="Fa" style="white-space: nowrap;">task_fn_t
- func</var>, <var class="Fa" style="white-space: nowrap;">void
- *context</var>);</p>
-<p class="Pp"><code class="Fn">TASK_INITIALIZER</code>(<var class="Fa" style="white-space: nowrap;">int
- priority</var>, <var class="Fa" style="white-space: nowrap;">task_fn_t
- func</var>, <var class="Fa" style="white-space: nowrap;">void
- *context</var>);</p>
-<p class="Pp"><code class="Fn">TASKQUEUE_DECLARE</code>(<var class="Fa" style="white-space: nowrap;">name</var>);</p>
-<p class="Pp"><code class="Fn">TASKQUEUE_DEFINE</code>(<var class="Fa" style="white-space: nowrap;">name</var>,
- <var class="Fa" style="white-space: nowrap;">taskqueue_enqueue_fn
- enqueue</var>, <var class="Fa" style="white-space: nowrap;">void
- *context</var>,
- <var class="Fa" style="white-space: nowrap;">init</var>);</p>
-<p class="Pp"><code class="Fn">TASKQUEUE_FAST_DEFINE</code>(<var class="Fa" style="white-space: nowrap;">name</var>,
- <var class="Fa" style="white-space: nowrap;">taskqueue_enqueue_fn
- enqueue</var>, <var class="Fa" style="white-space: nowrap;">void
- *context</var>,
- <var class="Fa" style="white-space: nowrap;">init</var>);</p>
-<p class="Pp"><code class="Fn">TASKQUEUE_DEFINE_THREAD</code>(<var class="Fa" style="white-space: nowrap;">name</var>);</p>
-<p class="Pp"><code class="Fn">TASKQUEUE_FAST_DEFINE_THREAD</code>(<var class="Fa" style="white-space: nowrap;">name</var>);</p>
-<p class="Pp"><code class="Fn">TIMEOUT_TASK_INIT</code>(<var class="Fa" style="white-space: nowrap;">struct
- taskqueue *queue</var>, <var class="Fa" style="white-space: nowrap;">struct
- timeout_task *timeout_task</var>,
- <var class="Fa" style="white-space: nowrap;">int priority</var>,
- <var class="Fa" style="white-space: nowrap;">task_fn_t func</var>,
- <var class="Fa" style="white-space: nowrap;">void *context</var>);</p>
-</section>
-<section class="Sh">
-<h1 class="Sh" id="DESCRIPTION"><a class="permalink" href="#DESCRIPTION">DESCRIPTION</a></h1>
-<p class="Pp">These functions provide a simple interface for asynchronous
- execution of code.</p>
-<p class="Pp" id="taskqueue_create">The function
- <a class="permalink" href="#taskqueue_create"><code class="Fn">taskqueue_create</code></a>()
- is used to create new queues. The arguments to
- <code class="Fn">taskqueue_create</code>() include a name that should be
- unique, a set of <a class="Xr">malloc(9)</a> flags that specify whether the
- call to
- <a class="permalink" href="#malloc"><code class="Fn" id="malloc">malloc</code></a>()
- is allowed to sleep, a function that is called from
- <code class="Fn">taskqueue_enqueue</code>() when a task is added to the
- queue, and a pointer to the memory location where the identity of the thread
- that services the queue is recorded. The function called from
- <code class="Fn">taskqueue_enqueue</code>() must arrange for the queue to be
- processed (for instance by scheduling a software interrupt or waking a
- kernel thread). The memory location where the thread identity is recorded is
- used to signal the service thread(s) to terminate--when this value is set to
- zero and the thread is signaled it will terminate. If the queue is intended
- for use in fast interrupt handlers
- <code class="Fn">taskqueue_create_fast</code>() should be used in place of
- <code class="Fn">taskqueue_create</code>().</p>
-<p class="Pp" id="taskqueue_free">The function
- <a class="permalink" href="#taskqueue_free"><code class="Fn">taskqueue_free</code></a>()
- should be used to free the memory used by the queue. Any tasks that are on
- the queue will be executed at this time after which the thread servicing the
- queue will be signaled that it should exit.</p>
-<p class="Pp" id="taskqueue_start_threads">Once a taskqueue has been created,
- its threads should be started using
- <a class="permalink" href="#taskqueue_start_threads"><code class="Fn">taskqueue_start_threads</code></a>(),
- <a class="permalink" href="#taskqueue_start_threads_cpuset"><code class="Fn" id="taskqueue_start_threads_cpuset">taskqueue_start_threads_cpuset</code></a>()
- or
- <a class="permalink" href="#taskqueue_start_threads_in_proc"><code class="Fn" id="taskqueue_start_threads_in_proc">taskqueue_start_threads_in_proc</code></a>().
- <code class="Fn">taskqueue_start_threads_cpuset</code>() takes a
- <var class="Va">cpuset</var> argument which will cause the threads which are
- started for the taskqueue to be restricted to run on the given CPUs.
- <code class="Fn">taskqueue_start_threads_in_proc</code>() takes a
- <var class="Va">proc</var> argument which will cause the threads which are
- started for the taskqueue to be assigned to the given kernel process.
- Callbacks may optionally be registered using
- <a class="permalink" href="#taskqueue_set_callback"><code class="Fn" id="taskqueue_set_callback">taskqueue_set_callback</code></a>().
- Currently, callbacks may be registered for the following purposes:</p>
-<dl class="Bl-tag">
- <dt id="TASKQUEUE_CALLBACK_TYPE_INIT"><a class="permalink" href="#TASKQUEUE_CALLBACK_TYPE_INIT"><code class="Dv">TASKQUEUE_CALLBACK_TYPE_INIT</code></a></dt>
- <dd>This callback is called by every thread in the taskqueue, before it
- executes any tasks. This callback must be set before the taskqueue's
- threads are started.</dd>
- <dt id="TASKQUEUE_CALLBACK_TYPE_SHUTDOWN"><a class="permalink" href="#TASKQUEUE_CALLBACK_TYPE_SHUTDOWN"><code class="Dv">TASKQUEUE_CALLBACK_TYPE_SHUTDOWN</code></a></dt>
- <dd>This callback is called by every thread in the taskqueue, after it
- executes its last task. This callback will always be called before the
- taskqueue structure is reclaimed.</dd>
-</dl>
-<p class="Pp" id="taskqueue_enqueue">To add a task to the list of tasks queued
- on a taskqueue, call
- <a class="permalink" href="#taskqueue_enqueue"><code class="Fn">taskqueue_enqueue</code></a>()
- with pointers to the queue and task. If the task's
- <var class="Va">ta_pending</var> field is non-zero, then it is simply
- incremented to reflect the number of times the task was enqueued, up to a
- cap of USHRT_MAX. Otherwise, the task is added to the list before the first
- task which has a lower <var class="Va">ta_priority</var> value or at the end
- of the list if no tasks have a lower priority. Enqueueing a task does not
- perform any memory allocation which makes it suitable for calling from an
- interrupt handler. This function will return <code class="Er">EPIPE</code>
- if the queue is being freed.</p>
-<p class="Pp" id="taskqueue_enqueue~2">When a task is executed, first it is
- removed from the queue, the value of <var class="Va">ta_pending</var> is
- recorded and then the field is zeroed. The function
- <var class="Va">ta_func</var> from the task structure is called with the
- value of the field <var class="Va">ta_context</var> as its first argument
- and the value of <var class="Va">ta_pending</var> as its second argument.
- After the function <var class="Va">ta_func</var> returns,
- <a class="Xr">wakeup(9)</a> is called on the task pointer passed to
- <a class="permalink" href="#taskqueue_enqueue~2"><code class="Fn">taskqueue_enqueue</code></a>().</p>
-<p class="Pp" id="taskqueue_enqueue_flags">The
- <a class="permalink" href="#taskqueue_enqueue_flags"><code class="Fn">taskqueue_enqueue_flags</code></a>()
- accepts an extra <var class="Va">flags</var> parameter which specifies a set
- of optional flags to alter the behavior of
- <code class="Fn">taskqueue_enqueue</code>(). It contains one or more of the
- following flags:</p>
-<dl class="Bl-tag">
- <dt id="TASKQUEUE_FAIL_IF_PENDING"><a class="permalink" href="#TASKQUEUE_FAIL_IF_PENDING"><code class="Dv">TASKQUEUE_FAIL_IF_PENDING</code></a></dt>
- <dd><code class="Fn">taskqueue_enqueue_flags</code>() fails if the task is
- already scheduled for execution. <code class="Er">EEXIST</code> is
- returned and the <var class="Va">ta_pending</var> counter value remains
- unchanged.</dd>
- <dt id="TASKQUEUE_FAIL_IF_CANCELING"><a class="permalink" href="#TASKQUEUE_FAIL_IF_CANCELING"><code class="Dv">TASKQUEUE_FAIL_IF_CANCELING</code></a></dt>
- <dd><code class="Fn">taskqueue_enqueue_flags</code>() fails if the task is in
- the canceling state and <code class="Er">ECANCELED</code> is
- returned.</dd>
-</dl>
-<p class="Pp" id="taskqueue_enqueue_timeout">The
- <a class="permalink" href="#taskqueue_enqueue_timeout"><code class="Fn">taskqueue_enqueue_timeout</code></a>()
- function is used to schedule the enqueue after the specified number of
- <var class="Va">ticks</var>. The
- <a class="permalink" href="#taskqueue_enqueue_timeout_sbt"><code class="Fn" id="taskqueue_enqueue_timeout_sbt">taskqueue_enqueue_timeout_sbt</code></a>()
- function provides finer control over the scheduling based on
- <var class="Va">sbt</var>, <var class="Va">pr</var>, and
- <var class="Va">flags</var>, as detailed in <a class="Xr">callout(9)</a>. If
- the <var class="Va">ticks</var> argument is negative, the already scheduled
- enqueueing is not re-scheduled. Otherwise, the task is scheduled for
- enqueueing in the future, after the absolute value of
- <var class="Va">ticks</var> is passed. This function returns -1 if the task
- is being drained. Otherwise, the number of pending calls is returned.</p>
-<p class="Pp" id="taskqueue_cancel">The
- <a class="permalink" href="#taskqueue_cancel"><code class="Fn">taskqueue_cancel</code></a>()
- function is used to cancel a task. The <var class="Va">ta_pending</var>
- count is cleared, and the old value returned in the reference parameter
- <var class="Fa">pendp</var>, if it is non-<code class="Dv">NULL</code>. If
- the task is currently running, <code class="Dv">EBUSY</code> is returned,
- otherwise 0. To implement a blocking
- <code class="Fn">taskqueue_cancel</code>() that waits for a running task to
- finish, it could look like:</p>
-<div class="Bd Pp Bd-indent Li">
-<pre>while (taskqueue_cancel(tq, task, NULL) != 0)
- taskqueue_drain(tq, task);</pre>
-</div>
-<p class="Pp" id="taskqueue_drain">Note that, as with
- <a class="permalink" href="#taskqueue_drain"><code class="Fn">taskqueue_drain</code></a>(),
- the caller is responsible for ensuring that the task is not re-enqueued
- after being canceled.</p>
-<p class="Pp" id="taskqueue_cancel_timeout">Similarly, the
- <a class="permalink" href="#taskqueue_cancel_timeout"><code class="Fn">taskqueue_cancel_timeout</code></a>()
- function is used to cancel the scheduled task execution.</p>
-<p class="Pp" id="taskqueue_drain~2">The
- <a class="permalink" href="#taskqueue_drain~2"><code class="Fn">taskqueue_drain</code></a>()
- function is used to wait for the task to finish, and the
- <a class="permalink" href="#taskqueue_drain_timeout"><code class="Fn" id="taskqueue_drain_timeout">taskqueue_drain_timeout</code></a>()
- function is used to wait for the scheduled task to finish. There is no
- guarantee that the task will not be enqueued after call to
- <code class="Fn">taskqueue_drain</code>(). If the caller wants to put the
- task into a known state, then before calling
- <code class="Fn">taskqueue_drain</code>() the caller should use out-of-band
- means to ensure that the task would not be enqueued. For example, if the
- task is enqueued by an interrupt filter, then the interrupt could be
- disabled.</p>
-<p class="Pp" id="taskqueue_drain_all">The
- <a class="permalink" href="#taskqueue_drain_all"><code class="Fn">taskqueue_drain_all</code></a>()
- function is used to wait for all pending and running tasks that are enqueued
- on the taskqueue to finish. Tasks posted to the taskqueue after
- <code class="Fn">taskqueue_drain_all</code>() begins processing, including
- pending enqueues scheduled by a previous call to
- <code class="Fn">taskqueue_enqueue_timeout</code>(), do not extend the wait
- time of <code class="Fn">taskqueue_drain_all</code>() and may complete after
- <code class="Fn">taskqueue_drain_all</code>() returns. The
- <a class="permalink" href="#taskqueue_quiesce"><code class="Fn" id="taskqueue_quiesce">taskqueue_quiesce</code></a>()
- function is used to wait for the queue to become empty and for all running
- tasks to finish. To avoid blocking indefinitely, the caller must ensure by
- some mechanism that tasks will eventually stop being posted to the
- queue.</p>
-<p class="Pp" id="taskqueue_block">The
- <a class="permalink" href="#taskqueue_block"><code class="Fn">taskqueue_block</code></a>()
- function blocks the taskqueue. It prevents any enqueued but not running
- tasks from being executed. Future calls to
- <code class="Fn">taskqueue_enqueue</code>() will enqueue tasks, but the
- tasks will not be run until <code class="Fn">taskqueue_unblock</code>() is
- called. Please note that <code class="Fn">taskqueue_block</code>() does not
- wait for any currently running tasks to finish. Thus, the
- <code class="Fn">taskqueue_block</code>() does not provide a guarantee that
- <code class="Fn">taskqueue_run</code>() is not running after
- <code class="Fn">taskqueue_block</code>() returns, but it does provide a
- guarantee that <code class="Fn">taskqueue_run</code>() will not be called
- again until <code class="Fn">taskqueue_unblock</code>() is called. If the
- caller requires a guarantee that <code class="Fn">taskqueue_run</code>() is
- not running, then this must be arranged by the caller. Note that if
- <code class="Fn">taskqueue_drain</code>() is called on a task that is
- enqueued on a taskqueue that is blocked by
- <code class="Fn">taskqueue_block</code>(), then
- <code class="Fn">taskqueue_drain</code>() can not return until the taskqueue
- is unblocked. This can result in a deadlock if the thread blocked in
- <code class="Fn">taskqueue_drain</code>() is the thread that is supposed to
- call <code class="Fn">taskqueue_unblock</code>(). Thus, use of
- <code class="Fn">taskqueue_drain</code>() after
- <code class="Fn">taskqueue_block</code>() is discouraged, because the state
- of the task can not be known in advance. The same caveat applies to
- <code class="Fn">taskqueue_drain_all</code>().</p>
-<p class="Pp" id="taskqueue_unblock">The
- <a class="permalink" href="#taskqueue_unblock"><code class="Fn">taskqueue_unblock</code></a>()
- function unblocks the previously blocked taskqueue. All enqueued tasks can
- be run after this call.</p>
-<p class="Pp" id="taskqueue_member">The
- <a class="permalink" href="#taskqueue_member"><code class="Fn">taskqueue_member</code></a>()
- function returns <span class="No">1</span> if the given thread
- <var class="Fa">td</var> is part of the given taskqueue
- <var class="Fa">queue</var> and <span class="No">0</span> otherwise.</p>
-<p class="Pp" id="taskqueue_run">The
- <a class="permalink" href="#taskqueue_run"><code class="Fn">taskqueue_run</code></a>()
- function will run all pending tasks in the specified
- <var class="Fa">queue</var>. Normally this function is only used
- internally.</p>
-<p class="Pp" id="TASK_INIT">A convenience macro,
- <a class="permalink" href="#TASK_INIT"><code class="Fn">TASK_INIT</code></a>(<var class="Fa">task</var>,
- <var class="Fa">priority</var>, <var class="Fa">func</var>,
- <var class="Fa">context</var>) is provided to initialise a
- <var class="Va">task</var> structure. The
- <a class="permalink" href="#TASK_INITIALIZER"><code class="Fn" id="TASK_INITIALIZER">TASK_INITIALIZER</code></a>()
- macro generates an initializer for a task structure. A macro
- <a class="permalink" href="#TIMEOUT_TASK_INIT"><code class="Fn" id="TIMEOUT_TASK_INIT">TIMEOUT_TASK_INIT</code></a>(<var class="Fa">queue</var>,
- <var class="Fa">timeout_task</var>, <var class="Fa">priority</var>,
- <var class="Fa">func</var>, <var class="Fa">context</var>) initializes the
- <var class="Va">timeout_task</var> structure. The values of
- <var class="Va">priority</var>, <var class="Va">func</var>, and
- <var class="Va">context</var> are simply copied into the task structure
- fields and the <var class="Va">ta_pending</var> field is cleared.</p>
-<p class="Pp" id="TASKQUEUE_DECLARE">Five macros
- <a class="permalink" href="#TASKQUEUE_DECLARE"><code class="Fn">TASKQUEUE_DECLARE</code></a>(<var class="Fa">name</var>),
- <a class="permalink" href="#TASKQUEUE_DEFINE"><code class="Fn" id="TASKQUEUE_DEFINE">TASKQUEUE_DEFINE</code></a>(<var class="Fa">name</var>,
- <var class="Fa">enqueue</var>, <var class="Fa">context</var>,
- <var class="Fa">init</var>),
- <code class="Fn">TASKQUEUE_FAST_DEFINE</code>(<var class="Fa">name</var>,
- <var class="Fa">enqueue</var>, <var class="Fa">context</var>,
- <var class="Fa">init</var>), and
- <code class="Fn">TASKQUEUE_DEFINE_THREAD</code>(<var class="Fa">name</var>)
- <code class="Fn">TASKQUEUE_FAST_DEFINE_THREAD</code>(<var class="Fa">name</var>)
- are used to declare a reference to a global queue, to define the
- implementation of the queue, and declare a queue that uses its own thread.
- The <code class="Fn">TASKQUEUE_DEFINE</code>() macro arranges to call
- <code class="Fn">taskqueue_create</code>() with the values of its
- <var class="Va">name</var>, <var class="Va">enqueue</var> and
- <var class="Va">context</var> arguments during system initialisation. After
- calling <code class="Fn">taskqueue_create</code>(), the
- <var class="Va">init</var> argument to the macro is executed as a C
- statement, allowing any further initialisation to be performed (such as
- registering an interrupt handler, etc.).</p>
-<p class="Pp" id="TASKQUEUE_DEFINE_THREAD">The
- <a class="permalink" href="#TASKQUEUE_DEFINE_THREAD"><code class="Fn">TASKQUEUE_DEFINE_THREAD</code></a>()
- macro defines a new taskqueue with its own kernel thread to serve tasks. The
- variable <var class="Vt">struct taskqueue *taskqueue_name</var> is used to
- enqueue tasks onto the queue.</p>
-<p class="Pp" id="TASKQUEUE_FAST_DEFINE"><a class="permalink" href="#TASKQUEUE_FAST_DEFINE"><code class="Fn">TASKQUEUE_FAST_DEFINE</code></a>()
- and
- <a class="permalink" href="#TASKQUEUE_FAST_DEFINE_THREAD"><code class="Fn" id="TASKQUEUE_FAST_DEFINE_THREAD">TASKQUEUE_FAST_DEFINE_THREAD</code></a>()
- act just like <code class="Fn">TASKQUEUE_DEFINE</code>() and
- <code class="Fn">TASKQUEUE_DEFINE_THREAD</code>() respectively but taskqueue
- is created with
- <a class="permalink" href="#taskqueue_create_fast"><code class="Fn" id="taskqueue_create_fast">taskqueue_create_fast</code></a>().</p>
-<section class="Ss">
-<h2 class="Ss" id="Predefined_Task_Queues"><a class="permalink" href="#Predefined_Task_Queues">Predefined
- Task Queues</a></h2>
-<p class="Pp">The system provides four global taskqueues,
- <var class="Va">taskqueue_fast</var>, <var class="Va">taskqueue_swi</var>,
- <var class="Va">taskqueue_swi_giant</var>, and
- <var class="Va">taskqueue_thread</var>. The
- <var class="Va">taskqueue_fast</var> queue is for swi handlers dispatched
- from fast interrupt handlers, where sleep mutexes cannot be used. The swi
- taskqueues are run via a software interrupt mechanism. The
- <var class="Va">taskqueue_swi</var> queue runs without the protection of the
- <var class="Va">Giant</var> kernel lock, and the
- <var class="Va">taskqueue_swi_giant</var> queue runs with the protection of
- the <var class="Va">Giant</var> kernel lock. The thread taskqueue
- <var class="Va">taskqueue_thread</var> runs in a kernel thread context, and
- tasks run from this thread do not run under the <var class="Va">Giant</var>
- kernel lock. If the caller wants to run under <var class="Va">Giant</var>,
- he should explicitly acquire and release <var class="Va">Giant</var> in his
- taskqueue handler routine.</p>
-<p class="Pp" id="taskqueue_enqueue~3">To use these queues, call
- <a class="permalink" href="#taskqueue_enqueue~3"><code class="Fn">taskqueue_enqueue</code></a>()
- with the value of the global taskqueue variable for the queue you wish to
- use.</p>
-<p class="Pp">The software interrupt queues can be used, for instance, for
- implementing interrupt handlers which must perform a significant amount of
- processing in the handler. The hardware interrupt handler would perform
- minimal processing of the interrupt and then enqueue a task to finish the
- work. This reduces to a minimum the amount of time spent with interrupts
- disabled.</p>
-<p class="Pp">The thread queue can be used, for instance, by interrupt level
- routines that need to call kernel functions that do things that can only be
- done from a thread context. (e.g., call malloc with the M_WAITOK flag.)</p>
-<p class="Pp">Note that tasks queued on shared taskqueues such as
- <var class="Va">taskqueue_swi</var> may be delayed an indeterminate amount
- of time before execution. If queueing delays cannot be tolerated then a
- private taskqueue should be created with a dedicated processing thread.</p>
-</section>
-</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">callout(9)</a>, <a class="Xr">intr_event(9)</a>,
- <a class="Xr">kthread(9)</a>, <a class="Xr">swi(9)</a></p>
-</section>
-<section class="Sh">
-<h1 class="Sh" id="HISTORY"><a class="permalink" href="#HISTORY">HISTORY</a></h1>
-<p class="Pp">This interface first appeared in <span class="Ux">FreeBSD
- 5.0</span>. There is a similar facility called work_queue in the Linux
- kernel.</p>
-</section>
-<section class="Sh">
-<h1 class="Sh" id="AUTHORS"><a class="permalink" href="#AUTHORS">AUTHORS</a></h1>
-<p class="Pp">This manual page was written by <span class="An">Doug
- Rabson</span>.</p>
-</section>
-</div>
-<table class="foot">
- <tr>
- <td class="foot-date">April 25, 2022</td>
- <td class="foot-os">FreeBSD 15.0</td>
- </tr>
-</table>