2 .\" Copyright (c) 2000 Doug Rabson
4 .\" All rights reserved.
6 .\" This program is free software.
8 .\" Redistribution and use in source and binary forms, with or without
9 .\" modification, are permitted provided that the following conditions
11 .\" 1. Redistributions of source code must retain the above copyright
12 .\" notice, this list of conditions and the following disclaimer.
13 .\" 2. Redistributions in binary form must reproduce the above copyright
14 .\" notice, this list of conditions and the following disclaimer in the
15 .\" documentation and/or other materials provided with the distribution.
17 .\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
18 .\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 .\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 .\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
21 .\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 .\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 .\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 .\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 .\" $FreeBSD: src/share/man/man9/taskqueue.9,v 1.21 2007/07/09 06:24:10 jmg Exp $
35 .Nm taskqueue_cancel ,
36 .Nm taskqueue_cancel_timeout ,
37 .Nm taskqueue_create ,
39 .Nm taskqueue_drain_timeout ,
40 .Nm taskqueue_enqueue ,
41 .Nm taskqueue_enqueue_timeout ,
45 .Nm taskqueue_start_threads ,
46 .Nm taskqueue_unblock ,
48 .Nm TASKQUEUE_DECLARE ,
50 .Nd asynchronous task execution
58 typedef void (*task_fn_t)(void *context, int pending);
60 typedef void (*taskqueue_enqueue_fn)(void *context);
63 STAILQ_ENTRY(task) ta_link; /* link for queue */
64 int ta_pending; /* count times queued */
65 int ta_priority; /* priority of task in queue */
66 task_fn_t ta_func; /* task handler */
67 void *ta_context; /* argument for handler */
70 .Ft struct taskqueue *
71 .Fn taskqueue_create "const char *name" "int mflags" "taskqueue_enqueue_fn enqueue" "void *context"
73 .Fn taskqueue_free "struct taskqueue *queue"
74 .Ft struct taskqueue *
75 .Fn taskqueue_find "const char *name"
77 .Fn taskqueue_enqueue "struct taskqueue *queue" "struct task *task"
79 .Fn taskqueue_enqueue_timeout "struct taskqueue *queue" "struct timeout_task *timeout_task" "int ticks"
81 .Fn taskqueue_cancel "struct taskqueue *queue" "struct task *task" "u_int *pendp"
83 .Fn taskqueue_cancel_timeout "struct taskqueue *queue" "struct timeout_task *timeout_task" "u_int *pendp"
85 .Fn taskqueue_run "struct taskqueue *queue"
87 .Fn taskqueue_drain "struct taskqueue *queue" "struct task *task"
89 .Fn taskqueue_drain_timeout "struct taskqueue *queue" "struct timeout_task *timeout_task"
91 .Fn taskqueue_block "struct taskqueue *queue"
93 .Fn taskqueue_unblock "struct taskqueue *queue"
95 .Fn taskqueue_start_threads "struct taskqueue **tqp" "int count" "int pri" "int ncpu" "const char *fmt" "..."
96 .Fn TASK_INIT "struct task *task" "int priority" "task_fn_t *func" "void *context"
97 .Fn TASKQUEUE_DECLARE "name"
98 .Fn TASKQUEUE_DEFINE "name" "taskqueue_enqueue_fn enqueue" "void *context" "init"
100 These functions provide a simple interface for asynchronous execution
105 is used to create new queues.
108 include a name that should be unique,
111 flags that specify whether the call to
114 and a function which is called from
115 .Fn taskqueue_enqueue
116 when a task is added to the queue
117 .\" XXX The rest of the sentence gets lots in relation to the first part.
118 to allow the queue to arrange to be run later
119 (for instance by scheduling a software interrupt or waking a kernel
124 should be used to remove the queue from the global list of queues
125 and free the memory used by the queue.
126 Any tasks that are on the queue will be executed at this time.
128 The system maintains a list of all queues which can be searched using
130 The first queue whose name matches is returned, otherwise
133 To add a task to the list of tasks queued on a taskqueue, call
134 .Fn taskqueue_enqueue
135 with pointers to the queue and task.
139 then it is simply incremented to reflect the number of times the task
142 the task is added to the list before the first task which has a lower
144 value or at the end of the list if no tasks have a lower priority.
145 Enqueueing a task does not perform any memory allocation which makes
146 it suitable for calling from an interrupt handler.
147 This function will return
149 if the queue is being freed.
151 To execute all the tasks on a queue,
154 When a task is executed,
155 first it is removed from the queue,
158 is recorded and then the field is zeroed.
161 from the task structure is called with the value of the field
163 as its first argument
166 as its second argument.
169 .Fn taskqueue_enqueue_timeout
170 is used to schedule the enqueue after the specified amount of
174 argument is negative, the already scheduled enqueueing is not re-scheduled.
175 Otherwise, the task is scheduled for enqueueing in the future,
176 after the absolute value of
182 function is used to cancel a task.
185 count is cleared, and the old value returned in the reference
190 If the task is currently running,
192 is returned, otherwise 0.
193 To implement a blocking
195 that waits for a running task to finish, it could look like:
196 .Bd -literal -offset indent
197 while (taskqueue_cancel(tq, task, NULL) != 0)
198 taskqueue_drain(tq, task);
202 .Fn taskqueue_drain ,
203 the caller is responsible for ensuring that the task is not re-enqueued
204 after being canceled.
207 .Fn taskqueue_cancel_timeout
208 function is used to cancel the scheduled task execution.
212 function is used to wait for the task to finish, and
214 .Fn taskqueue_drain_timeout
215 function is used to wait for the scheduled task to finish.
216 There is no guarantee that the task will not be
217 enqueued after call to
218 .Fn taskqueue_drain .
222 function is used to block a taskqueue.
223 When a taskqueue is blocked, calls to
224 .Fn taskqueue_enqueue
225 will still enqueue tasks but
226 they will not be run until the taskqueue is unblocked by calling
227 .Fn taskqueue_unblock .
230 .Fn taskqueue_start_threads
231 function is used to create and start
233 dedicated threads for the taskqueue specified by
235 These threads will be created with the priority specified by
237 and the name given by
239 with _N appended to it, where N is the number of the thread.
246 threads will be allocated to a different
247 CPU among all available CPUs in a round robin fashion.
248 The taskqueue specified by
250 must be created previously by calling
255 .Fa taskqueue_thread_enqueue .
259 is provided to initialise a
267 are simply copied into the task structure fields and the
272 .Fn TASKQUEUE_DECLARE
275 are used to declare a reference to a global queue,
276 and to define the implementation of the queue.
279 macro arranges to call
281 with the values of its
286 arguments during system initialisation.
288 .Fn taskqueue_create ,
291 argument to the macro is executed as a C statement,
292 allowing any further initialisation to be performed
293 (such as registering an interrupt handler etc.)
295 The system provides two global taskqueues,
298 .Va taskqueue_swi_mp ,
299 which are run via a software interrupt mechanism.
300 To use these queues, call
301 .Fn taskqueue_enqueue
302 with the value of the global variable
305 .Va taskqueue_swi_mp .
309 acquires the mplock for its tasks,
311 is intended for mpsafe tasks and no mplock will be acquired for them.
312 These queues can be used,
313 for instance, for implementing interrupt handlers which must perform a
314 significant amount of processing in the handler.
315 The hardware interrupt handler would perform minimal processing of the
316 interrupt and then enqueue a task to finish the work.
317 This reduces to a minimum
318 the amount of time spent with interrupts disabled.
324 This interface first appeared in
326 There is a similar facility called work_queue in the Linux kernel.
328 This manual page was written by