diff options
Diffstat (limited to 'static/freebsd/man9/taskqueue.9 4.html')
| -rw-r--r-- | static/freebsd/man9/taskqueue.9 4.html | 494 |
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> — - <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 - <<a class="In">sys/param.h</a>></code> - <br/> - <code class="In">#include <<a class="In">sys/kernel.h</a>></code> - <br/> - <code class="In">#include <<a class="In">sys/malloc.h</a>></code> - <br/> - <code class="In">#include <<a class="In">sys/queue.h</a>></code> - <br/> - <code class="In">#include <<a class="In">sys/taskqueue.h</a>></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> |
