3 .\" Copyright (c) 2000 Doug Rabson
5 .\" All rights reserved.
7 .\" This program is free software.
9 .\" Redistribution and use in source and binary forms, with or without
10 .\" modification, are permitted provided that the following conditions
12 .\" 1. Redistributions of source code must retain the above copyright
13 .\" notice, this list of conditions and the following disclaimer.
14 .\" 2. Redistributions in binary form must reproduce the above copyright
15 .\" notice, this list of conditions and the following disclaimer in the
16 .\" documentation and/or other materials provided with the distribution.
18 .\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
19 .\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 .\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 .\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
22 .\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 .\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 .\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 .\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 .Nd asynchronous task execution
44 typedef void (*task_fn_t)(void *context, int pending);
46 typedef void (*taskqueue_enqueue_fn)(void *context);
49 STAILQ_ENTRY(task) ta_link; /* link for queue */
50 u_short ta_pending; /* count times queued */
51 u_short ta_priority; /* priority of task in queue */
52 task_fn_t ta_func; /* task handler */
53 void *ta_context; /* argument for handler */
56 enum taskqueue_callback_type {
57 TASKQUEUE_CALLBACK_TYPE_INIT,
58 TASKQUEUE_CALLBACK_TYPE_SHUTDOWN,
61 typedef void (*taskqueue_callback_fn)(void *context);
65 .Ft struct taskqueue *
66 .Fn taskqueue_create "const char *name" "int mflags" "taskqueue_enqueue_fn enqueue" "void *context"
67 .Ft struct taskqueue *
68 .Fn taskqueue_create_fast "const char *name" "int mflags" "taskqueue_enqueue_fn enqueue" "void *context"
70 .Fn taskqueue_start_threads "struct taskqueue **tqp" "int count" "int pri" "const char *name" "..."
72 .Fo taskqueue_start_threads_cpuset
73 .Fa "struct taskqueue **tqp" "int count" "int pri" "cpuset_t *mask"
74 .Fa "const char *name" "..."
77 .Fo taskqueue_start_threads_in_proc
78 .Fa "struct taskqueue **tqp" "int count" "int pri" "struct proc *proc"
79 .Fa "const char *name" "..."
82 .Fn taskqueue_set_callback "struct taskqueue *queue" "enum taskqueue_callback_type cb_type" "taskqueue_callback_fn callback" "void *context"
84 .Fn taskqueue_free "struct taskqueue *queue"
86 .Fn taskqueue_enqueue "struct taskqueue *queue" "struct task *task"
88 .Fn taskqueue_enqueue_timeout "struct taskqueue *queue" "struct timeout_task *timeout_task" "int ticks"
90 .Fn taskqueue_enqueue_timeout_sbt "struct taskqueue *queue" "struct timeout_task *timeout_task" "sbintime_t sbt" "sbintime_t pr" "int flags"
92 .Fn taskqueue_cancel "struct taskqueue *queue" "struct task *task" "u_int *pendp"
94 .Fn taskqueue_cancel_timeout "struct taskqueue *queue" "struct timeout_task *timeout_task" "u_int *pendp"
96 .Fn taskqueue_drain "struct taskqueue *queue" "struct task *task"
98 .Fn taskqueue_drain_timeout "struct taskqueue *queue" "struct timeout_task *timeout_task"
100 .Fn taskqueue_drain_all "struct taskqueue *queue"
102 .Fn taskqueue_quiesce "struct taskqueue *queue"
104 .Fn taskqueue_block "struct taskqueue *queue"
106 .Fn taskqueue_unblock "struct taskqueue *queue"
108 .Fn taskqueue_member "struct taskqueue *queue" "struct thread *td"
110 .Fn taskqueue_run "struct taskqueue *queue"
111 .Fn TASK_INIT "struct task *task" "int priority" "task_fn_t func" "void *context"
112 .Fn TASK_INITIALIZER "int priority" "task_fn_t func" "void *context"
113 .Fn TASKQUEUE_DECLARE "name"
114 .Fn TASKQUEUE_DEFINE "name" "taskqueue_enqueue_fn enqueue" "void *context" "init"
115 .Fn TASKQUEUE_FAST_DEFINE "name" "taskqueue_enqueue_fn enqueue" "void *context" "init"
116 .Fn TASKQUEUE_DEFINE_THREAD "name"
117 .Fn TASKQUEUE_FAST_DEFINE_THREAD "name"
118 .Fn TIMEOUT_TASK_INIT "struct taskqueue *queue" "struct timeout_task *timeout_task" "int priority" "task_fn_t func" "void *context"
120 These functions provide a simple interface for asynchronous execution
125 is used to create new queues.
128 include a name that should be unique,
131 flags that specify whether the call to
134 a function that is called from
135 .Fn taskqueue_enqueue
136 when a task is added to the queue,
137 and a pointer to the memory location where the identity of the
138 thread that services the queue is recorded.
139 .\" XXX The rest of the sentence gets lots in relation to the first part.
140 The function called from
141 .Fn taskqueue_enqueue
142 must arrange for the queue to be processed
143 (for instance by scheduling a software interrupt or waking a kernel
145 The memory location where the thread identity is recorded is used
146 to signal the service thread(s) to terminate--when this value is set to
147 zero and the thread is signaled it will terminate.
148 If the queue is intended for use in fast interrupt handlers
149 .Fn taskqueue_create_fast
150 should be used in place of
151 .Fn taskqueue_create .
155 should be used to free the memory used by the queue.
156 Any tasks that are on the queue will be executed at this time after
157 which the thread servicing the queue will be signaled that it should exit.
159 Once a taskqueue has been created, its threads should be started using
160 .Fn taskqueue_start_threads ,
161 .Fn taskqueue_start_threads_cpuset
163 .Fn taskqueue_start_threads_in_proc .
164 .Fn taskqueue_start_threads_cpuset
167 argument which will cause the threads which are started for the taskqueue
168 to be restricted to run on the given CPUs.
169 .Fn taskqueue_start_threads_in_proc
172 argument which will cause the threads which are started for the taskqueue
173 to be assigned to the given kernel process.
174 Callbacks may optionally be registered using
175 .Fn taskqueue_set_callback .
176 Currently, callbacks may be registered for the following purposes:
177 .Bl -tag -width TASKQUEUE_CALLBACK_TYPE_SHUTDOWN
178 .It Dv TASKQUEUE_CALLBACK_TYPE_INIT
179 This callback is called by every thread in the taskqueue, before it executes
181 This callback must be set before the taskqueue's threads are started.
182 .It Dv TASKQUEUE_CALLBACK_TYPE_SHUTDOWN
183 This callback is called by every thread in the taskqueue, after it executes
185 This callback will always be called before the taskqueue structure is
189 To add a task to the list of tasks queued on a taskqueue, call
190 .Fn taskqueue_enqueue
191 with pointers to the queue and task.
195 then it is simply incremented to reflect the number of times the task
196 was enqueued, up to a cap of USHRT_MAX.
198 the task is added to the list before the first task which has a lower
200 value or at the end of the list if no tasks have a lower priority.
201 Enqueueing a task does not perform any memory allocation which makes
202 it suitable for calling from an interrupt handler.
203 This function will return
205 if the queue is being freed.
207 When a task is executed,
208 first it is removed from the queue,
211 is recorded and then the field is zeroed.
214 from the task structure is called with the value of the field
216 as its first argument
219 as its second argument.
224 is called on the task pointer passed to
225 .Fn taskqueue_enqueue .
228 .Fn taskqueue_enqueue_timeout
229 function is used to schedule the enqueue after the specified number of
232 .Fn taskqueue_enqueue_timeout_sbt
233 function provides finer control over the scheduling based on
240 Only non-fast task queues can be used for
245 argument is negative, the already scheduled enqueueing is not re-scheduled.
246 Otherwise, the task is scheduled for enqueueing in the future,
247 after the absolute value of
250 This function returns -1 if the task is being drained.
251 Otherwise, the number of pending calls is returned.
255 function is used to cancel a task.
258 count is cleared, and the old value returned in the reference
263 If the task is currently running,
265 is returned, otherwise 0.
266 To implement a blocking
268 that waits for a running task to finish, it could look like:
269 .Bd -literal -offset indent
270 while (taskqueue_cancel(tq, task, NULL) != 0)
271 taskqueue_drain(tq, task);
275 .Fn taskqueue_drain ,
276 the caller is responsible for ensuring that the task is not re-enqueued
277 after being canceled.
280 .Fn taskqueue_cancel_timeout
281 function is used to cancel the scheduled task execution.
285 function is used to wait for the task to finish, and
287 .Fn taskqueue_drain_timeout
288 function is used to wait for the scheduled task to finish.
289 There is no guarantee that the task will not be
290 enqueued after call to
291 .Fn taskqueue_drain .
292 If the caller wants to put the task into a known state,
295 the caller should use out-of-band means to ensure that the task
296 would not be enqueued.
297 For example, if the task is enqueued by an interrupt filter, then
298 the interrupt could be disabled.
301 .Fn taskqueue_drain_all
302 function is used to wait for all pending and running tasks that
303 are enqueued on the taskqueue to finish.
304 Tasks posted to the taskqueue after
305 .Fn taskqueue_drain_all
307 including pending enqueues scheduled by a previous call to
308 .Fn taskqueue_enqueue_timeout ,
309 do not extend the wait time of
310 .Fn taskqueue_drain_all
311 and may complete after
312 .Fn taskqueue_drain_all
315 .Fn taskqueue_quiesce
316 function is used to wait for the queue to become empty and for all
317 running tasks to finish.
318 To avoid blocking indefinitely, the caller must ensure by some mechanism
319 that tasks will eventually stop being posted to the queue.
323 function blocks the taskqueue.
324 It prevents any enqueued but not running tasks from being executed.
326 .Fn taskqueue_enqueue
327 will enqueue tasks, but the tasks will not be run until
328 .Fn taskqueue_unblock
332 does not wait for any currently running tasks to finish.
335 does not provide a guarantee that
339 returns, but it does provide a guarantee that
341 will not be called again
343 .Fn taskqueue_unblock
345 If the caller requires a guarantee that
347 is not running, then this must be arranged by the caller.
350 is called on a task that is enqueued on a taskqueue that is blocked by
351 .Fn taskqueue_block ,
354 can not return until the taskqueue is unblocked.
355 This can result in a deadlock if the thread blocked in
357 is the thread that is supposed to call
358 .Fn taskqueue_unblock .
363 is discouraged, because the state of the task can not be known in advance.
364 The same caveat applies to
365 .Fn taskqueue_drain_all .
368 .Fn taskqueue_unblock
369 function unblocks the previously blocked taskqueue.
370 All enqueued tasks can be run after this call.
378 is part of the given taskqueue
386 function will run all pending tasks in the specified
388 Normally this function is only used internally.
391 .Fn TASK_INIT "task" "priority" "func" "context"
392 is provided to initialise a
397 macro generates an initializer for a task structure.
399 .Fn TIMEOUT_TASK_INIT "queue" "timeout_task" "priority" "func" "context"
408 are simply copied into the task structure fields and the
413 .Fn TASKQUEUE_DECLARE "name" ,
414 .Fn TASKQUEUE_DEFINE "name" "enqueue" "context" "init" ,
415 .Fn TASKQUEUE_FAST_DEFINE "name" "enqueue" "context" "init" ,
417 .Fn TASKQUEUE_DEFINE_THREAD "name"
418 .Fn TASKQUEUE_FAST_DEFINE_THREAD "name"
419 are used to declare a reference to a global queue, to define the
420 implementation of the queue, and declare a queue that uses its own thread.
423 macro arranges to call
425 with the values of its
430 arguments during system initialisation.
432 .Fn taskqueue_create ,
435 argument to the macro is executed as a C statement,
436 allowing any further initialisation to be performed
437 (such as registering an interrupt handler, etc.).
440 .Fn TASKQUEUE_DEFINE_THREAD
441 macro defines a new taskqueue with its own kernel thread to serve tasks.
443 .Vt struct taskqueue *taskqueue_name
444 is used to enqueue tasks onto the queue.
446 .Fn TASKQUEUE_FAST_DEFINE
448 .Fn TASKQUEUE_FAST_DEFINE_THREAD
452 .Fn TASKQUEUE_DEFINE_THREAD
453 respectively but taskqueue is created with
454 .Fn taskqueue_create_fast .
455 .Ss Predefined Task Queues
456 The system provides four global taskqueues,
459 .Va taskqueue_swi_giant ,
461 .Va taskqueue_thread .
464 queue is for swi handlers dispatched from fast interrupt handlers,
465 where sleep mutexes cannot be used.
466 The swi taskqueues are run via a software interrupt mechanism.
469 queue runs without the protection of the
472 .Va taskqueue_swi_giant
473 queue runs with the protection of the
478 runs in a kernel thread context, and tasks run from this thread do
482 If the caller wants to run under
484 he should explicitly acquire and release
486 in his taskqueue handler routine.
490 .Fn taskqueue_enqueue
491 with the value of the global taskqueue variable for the queue you wish to
494 The software interrupt queues can be used,
495 for instance, for implementing interrupt handlers which must perform a
496 significant amount of processing in the handler.
497 The hardware interrupt handler would perform minimal processing of the
498 interrupt and then enqueue a task to finish the work.
499 This reduces to a minimum
500 the amount of time spent with interrupts disabled.
502 The thread queue can be used, for instance, by interrupt level routines
503 that need to call kernel functions that do things that can only be done
504 from a thread context.
505 (e.g., call malloc with the M_WAITOK flag.)
507 Note that tasks queued on shared taskqueues such as
509 may be delayed an indeterminate amount of time before execution.
510 If queueing delays cannot be tolerated then a private taskqueue should
511 be created with a dedicated processing thread.
518 This interface first appeared in
520 There is a similar facility called work_queue in the Linux kernel.
522 This manual page was written by