]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - share/man/man9/taskqueue.9
Merge ACPICA 20150619.
[FreeBSD/FreeBSD.git] / share / man / man9 / taskqueue.9
1 .\" -*- nroff -*-
2 .\"
3 .\" Copyright (c) 2000 Doug Rabson
4 .\"
5 .\" All rights reserved.
6 .\"
7 .\" This program is free software.
8 .\"
9 .\" Redistribution and use in source and binary forms, with or without
10 .\" modification, are permitted provided that the following conditions
11 .\" are met:
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.
17 .\"
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.
28 .\"
29 .\" $FreeBSD$
30 .\"
31 .Dd January 4, 2015
32 .Dt TASKQUEUE 9
33 .Os
34 .Sh NAME
35 .Nm taskqueue
36 .Nd asynchronous task execution
37 .Sh SYNOPSIS
38 .In sys/param.h
39 .In sys/kernel.h
40 .In sys/malloc.h
41 .In sys/queue.h
42 .In sys/taskqueue.h
43 .Bd -literal
44 typedef void (*task_fn_t)(void *context, int pending);
45
46 typedef void (*taskqueue_enqueue_fn)(void *context);
47
48 struct task {
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 */
54 };
55
56 enum taskqueue_callback_type {
57         TASKQUEUE_CALLBACK_TYPE_INIT,
58         TASKQUEUE_CALLBACK_TYPE_SHUTDOWN,
59 };
60
61 typedef void (*taskqueue_callback_fn)(void *context);
62
63 struct timeout_task;
64 .Ed
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"
69 .Ft int
70 .Fn taskqueue_start_threads "struct taskqueue **tqp" "int count" "int pri" "const char *name" "..."
71 .Ft int
72 .Fo taskqueue_start_threads_pinned
73 .Fa "struct taskqueue **tqp" "int count" "int pri" "int cpu_id"
74 .Fa "const char *name" "..."
75 .Fc
76 .Ft void
77 .Fn taskqueue_set_callback "struct taskqueue *queue" "enum taskqueue_callback_type cb_type" "taskqueue_callback_fn callback" "void *context"
78 .Ft void
79 .Fn taskqueue_free "struct taskqueue *queue"
80 .Ft int
81 .Fn taskqueue_enqueue "struct taskqueue *queue" "struct task *task"
82 .Ft int
83 .Fn taskqueue_enqueue_fast "struct taskqueue *queue" "struct task *task"
84 .Ft int
85 .Fn taskqueue_enqueue_timeout "struct taskqueue *queue" "struct timeout_task *timeout_task" "int ticks"
86 .Ft int
87 .Fn taskqueue_cancel "struct taskqueue *queue" "struct task *task" "u_int *pendp"
88 .Ft int
89 .Fn taskqueue_cancel_timeout "struct taskqueue *queue" "struct timeout_task *timeout_task" "u_int *pendp"
90 .Ft void
91 .Fn taskqueue_drain "struct taskqueue *queue" "struct task *task"
92 .Ft void
93 .Fn taskqueue_drain_timeout "struct taskqueue *queue" "struct timeout_task *timeout_task"
94 .Ft void
95 .Fn taskqueue_drain_all "struct taskqueue *queue"
96 .Ft void
97 .Fn taskqueue_block "struct taskqueue *queue"
98 .Ft void
99 .Fn taskqueue_unblock "struct taskqueue *queue"
100 .Ft int
101 .Fn taskqueue_member "struct taskqueue *queue" "struct thread *td"
102 .Ft void
103 .Fn taskqueue_run "struct taskqueue *queue"
104 .Fn TASK_INIT "struct task *task" "int priority" "task_fn_t func" "void *context"
105 .Fn TASK_INITIALIZER "int priority" "task_fn_t func" "void *context"
106 .Fn TASKQUEUE_DECLARE "name"
107 .Fn TASKQUEUE_DEFINE "name" "taskqueue_enqueue_fn enqueue" "void *context" "init"
108 .Fn TASKQUEUE_FAST_DEFINE "name" "taskqueue_enqueue_fn enqueue" "void *context" "init"
109 .Fn TASKQUEUE_DEFINE_THREAD "name"
110 .Fn TASKQUEUE_FAST_DEFINE_THREAD "name"
111 .Fn TIMEOUT_TASK_INIT "struct taskqueue *queue" "struct timeout_task *timeout_task" "int priority" "task_fn_t func" "void *context"
112 .Sh DESCRIPTION
113 These functions provide a simple interface for asynchronous execution
114 of code.
115 .Pp
116 The function
117 .Fn taskqueue_create
118 is used to create new queues.
119 The arguments to
120 .Fn taskqueue_create
121 include a name that should be unique,
122 a set of
123 .Xr malloc 9
124 flags that specify whether the call to
125 .Fn malloc
126 is allowed to sleep,
127 a function that is called from
128 .Fn taskqueue_enqueue
129 when a task is added to the queue,
130 and a pointer to the memory location where the identity of the
131 thread that services the queue is recorded.
132 .\" XXX The rest of the sentence gets lots in relation to the first part.
133 The function called from
134 .Fn taskqueue_enqueue
135 must arrange for the queue to be processed
136 (for instance by scheduling a software interrupt or waking a kernel
137 thread).
138 The memory location where the thread identity is recorded is used
139 to signal the service thread(s) to terminate--when this value is set to
140 zero and the thread is signaled it will terminate.
141 If the queue is intended for use in fast interrupt handlers
142 .Fn taskqueue_create_fast
143 should be used in place of
144 .Fn taskqueue_create .
145 .Pp
146 The function
147 .Fn taskqueue_free
148 should be used to free the memory used by the queue.
149 Any tasks that are on the queue will be executed at this time after
150 which the thread servicing the queue will be signaled that it should exit.
151 .Pp
152 Once a taskqueue has been created, its threads should be started using
153 .Fn taskqueue_start_threads
154 or
155 .Fn taskqueue_start_threads_pinned .
156 .Fn taskqueue_start_threads_pinned
157 takes a
158 .Va cpu_id
159 argument which will cause the threads which are started for the taskqueue
160 to be pinned to run on the given CPU.
161 Callbacks may optionally be registered using
162 .Fn taskqueue_set_callback .
163 Currently, callbacks may be registered for the following purposes:
164 .Bl -tag -width TASKQUEUE_CALLBACK_TYPE_SHUTDOWN
165 .It Dv TASKQUEUE_CALLBACK_TYPE_INIT
166 This callback is called by every thread in the taskqueue, before it executes
167 any tasks.
168 This callback must be set before the taskqueue's threads are started.
169 .It Dv TASKQUEUE_CALLBACK_TYPE_SHUTDOWN
170 This callback is called by every thread in the taskqueue, after it executes
171 its last task.
172 This callback will always be called before the taskqueue structure is
173 reclaimed.
174 .El
175 .Pp
176 To add a task to the list of tasks queued on a taskqueue, call
177 .Fn taskqueue_enqueue
178 with pointers to the queue and task.
179 If the task's
180 .Va ta_pending
181 field is non-zero,
182 then it is simply incremented to reflect the number of times the task
183 was enqueued, up to a cap of USHRT_MAX.
184 Otherwise,
185 the task is added to the list before the first task which has a lower
186 .Va ta_priority
187 value or at the end of the list if no tasks have a lower priority.
188 Enqueueing a task does not perform any memory allocation which makes
189 it suitable for calling from an interrupt handler.
190 This function will return
191 .Er EPIPE
192 if the queue is being freed.
193 .Pp
194 The function
195 .Fn taskqueue_enqueue_fast
196 should be used in place of
197 .Fn taskqueue_enqueue
198 when the enqueuing must happen from a fast interrupt handler.
199 This method uses spin locks to avoid the possibility of sleeping in the fast
200 interrupt context.
201 .Pp
202 When a task is executed,
203 first it is removed from the queue,
204 the value of
205 .Va ta_pending
206 is recorded and then the field is zeroed.
207 The function
208 .Va ta_func
209 from the task structure is called with the value of the field
210 .Va ta_context
211 as its first argument
212 and the value of
213 .Va ta_pending
214 as its second argument.
215 After the function
216 .Va ta_func
217 returns,
218 .Xr wakeup 9
219 is called on the task pointer passed to
220 .Fn taskqueue_enqueue .
221 .Pp
222 The
223 .Fn taskqueue_enqueue_timeout
224 is used to schedule the enqueue after the specified amount of
225 .Va ticks .
226 Only non-fast task queues can be used for
227 .Va timeout_task
228 scheduling.
229 If the
230 .Va ticks
231 argument is negative, the already scheduled enqueueing is not re-scheduled.
232 Otherwise, the task is scheduled for enqueueing in the future,
233 after the absolute value of
234 .Va ticks
235 is passed.
236 .Pp
237 The
238 .Fn taskqueue_cancel
239 function is used to cancel a task.
240 The
241 .Va ta_pending
242 count is cleared, and the old value returned in the reference
243 parameter
244 .Fa pendp ,
245 if it is
246 .Pf non- Dv NULL .
247 If the task is currently running,
248 .Dv EBUSY
249 is returned, otherwise 0.
250 To implement a blocking
251 .Fn taskqueue_cancel
252 that waits for a running task to finish, it could look like:
253 .Bd -literal -offset indent
254 while (taskqueue_cancel(tq, task, NULL) != 0)
255         taskqueue_drain(tq, task);
256 .Ed
257 .Pp
258 Note that, as with
259 .Fn taskqueue_drain ,
260 the caller is responsible for ensuring that the task is not re-enqueued
261 after being canceled.
262 .Pp
263 Similarly, the
264 .Fn taskqueue_cancel_timeout
265 function is used to cancel the scheduled task execution.
266 .Pp
267 The
268 .Fn taskqueue_drain
269 function is used to wait for the task to finish, and
270 the
271 .Fn taskqueue_drain_timeout
272 function is used to wait for the scheduled task to finish.
273 There is no guarantee that the task will not be
274 enqueued after call to
275 .Fn taskqueue_drain .
276 If the caller wants to put the task into a known state,
277 then before calling
278 .Fn taskqueue_drain
279 the caller should use out-of-band means to ensure that the task
280 would not be enqueued.
281 For example, if the task is enqueued by an interrupt filter, then
282 the interrupt could be disabled.
283 .Pp
284 The
285 .Fn taskqueue_drain_all
286 function is used to wait for all pending and running tasks that
287 are enqueued on the taskqueue to finish.
288 Tasks posted to the taskqueue after
289 .Fn taskqueue_drain_all
290 begins processing,
291 including pending enqueues scheduled by a previous call to
292 .Fn taskqueue_enqueue_timeout ,
293 do not extend the wait time of
294 .Fn taskqueue_drain_all
295 and may complete after
296 .Fn taskqueue_drain_all
297 returns.
298 .Pp
299 The
300 .Fn taskqueue_block
301 function blocks the taskqueue.
302 It prevents any enqueued but not running tasks from being executed.
303 Future calls to
304 .Fn taskqueue_enqueue
305 will enqueue tasks, but the tasks will not be run until
306 .Fn taskqueue_unblock
307 is called.
308 Please note that
309 .Fn taskqueue_block
310 does not wait for any currently running tasks to finish.
311 Thus, the
312 .Fn taskqueue_block
313 does not provide a guarantee that
314 .Fn taskqueue_run
315 is not running after
316 .Fn taskqueue_block
317 returns, but it does provide a guarantee that
318 .Fn taskqueue_run
319 will not be called again
320 until
321 .Fn taskqueue_unblock
322 is called.
323 If the caller requires a guarantee that
324 .Fn taskqueue_run
325 is not running, then this must be arranged by the caller.
326 Note that if
327 .Fn taskqueue_drain
328 is called on a task that is enqueued on a taskqueue that is blocked by
329 .Fn taskqueue_block ,
330 then
331 .Fn taskqueue_drain
332 can not return until the taskqueue is unblocked.
333 This can result in a deadlock if the thread blocked in
334 .Fn taskqueue_drain
335 is the thread that is supposed to call
336 .Fn taskqueue_unblock .
337 Thus, use of
338 .Fn taskqueue_drain
339 after
340 .Fn taskqueue_block
341 is discouraged, because the state of the task can not be known in advance.
342 The same caveat applies to
343 .Fn taskqueue_drain_all .
344 .Pp
345 The
346 .Fn taskqueue_unblock
347 function unblocks the previously blocked taskqueue.
348 All enqueued tasks can be run after this call.
349 .Pp
350 The
351 .Fn taskqueue_member
352 function returns
353 .No 1
354 if the given thread
355 .Fa td
356 is part of the given taskqueue
357 .Fa queue
358 and
359 .No 0
360 otherwise.
361 .Pp
362 The
363 .Fn taskqueue_run
364 function will run all pending tasks in the specified
365 .Fa queue .
366 Normally this function is only used internally.
367 .Pp
368 A convenience macro,
369 .Fn TASK_INIT "task" "priority" "func" "context"
370 is provided to initialise a
371 .Va task
372 structure.
373 The
374 .Fn TASK_INITIALIZER
375 macro generates an initializer for a task structure.
376 A macro
377 .Fn TIMEOUT_TASK_INIT "queue" "timeout_task" "priority" "func" "context"
378 initializes the
379 .Va timeout_task
380 structure.
381 The values of
382 .Va priority ,
383 .Va func ,
384 and
385 .Va context
386 are simply copied into the task structure fields and the
387 .Va ta_pending
388 field is cleared.
389 .Pp
390 Five macros
391 .Fn TASKQUEUE_DECLARE "name" ,
392 .Fn TASKQUEUE_DEFINE "name" "enqueue" "context" "init" ,
393 .Fn TASKQUEUE_FAST_DEFINE "name" "enqueue" "context" "init" ,
394 and
395 .Fn TASKQUEUE_DEFINE_THREAD "name"
396 .Fn TASKQUEUE_FAST_DEFINE_THREAD "name"
397 are used to declare a reference to a global queue, to define the
398 implementation of the queue, and declare a queue that uses its own thread.
399 The
400 .Fn TASKQUEUE_DEFINE
401 macro arranges to call
402 .Fn taskqueue_create
403 with the values of its
404 .Va name ,
405 .Va enqueue
406 and
407 .Va context
408 arguments during system initialisation.
409 After calling
410 .Fn taskqueue_create ,
411 the
412 .Va init
413 argument to the macro is executed as a C statement,
414 allowing any further initialisation to be performed
415 (such as registering an interrupt handler etc.)
416 .Pp
417 The
418 .Fn TASKQUEUE_DEFINE_THREAD
419 macro defines a new taskqueue with its own kernel thread to serve tasks.
420 The variable
421 .Vt struct taskqueue *taskqueue_name
422 is used to enqueue tasks onto the queue.
423 .Pp
424 .Fn TASKQUEUE_FAST_DEFINE
425 and
426 .Fn TASKQUEUE_FAST_DEFINE_THREAD
427 act just like
428 .Fn TASKQUEUE_DEFINE
429 and
430 .Fn TASKQUEUE_DEFINE_THREAD
431 respectively but taskqueue is created with
432 .Fn taskqueue_create_fast .
433 .Ss Predefined Task Queues
434 The system provides four global taskqueues,
435 .Va taskqueue_fast ,
436 .Va taskqueue_swi ,
437 .Va taskqueue_swi_giant ,
438 and
439 .Va taskqueue_thread .
440 The
441 .Va taskqueue_fast
442 queue is for swi handlers dispatched from fast interrupt handlers,
443 where sleep mutexes cannot be used.
444 The swi taskqueues are run via a software interrupt mechanism.
445 The
446 .Va taskqueue_swi
447 queue runs without the protection of the
448 .Va Giant
449 kernel lock, and the
450 .Va taskqueue_swi_giant
451 queue runs with the protection of the
452 .Va Giant
453 kernel lock.
454 The thread taskqueue
455 .Va taskqueue_thread
456 runs in a kernel thread context, and tasks run from this thread do
457 not run under the
458 .Va Giant
459 kernel lock.
460 If the caller wants to run under
461 .Va Giant ,
462 he should explicitly acquire and release
463 .Va Giant
464 in his taskqueue handler routine.
465 .Pp
466 To use these queues,
467 call
468 .Fn taskqueue_enqueue
469 with the value of the global taskqueue variable for the queue you wish to
470 use
471 .Va ( taskqueue_swi ,
472 .Va taskqueue_swi_giant ,
473 or
474 .Va taskqueue_thread ) .
475 Use
476 .Fn taskqueue_enqueue_fast
477 for the global taskqueue variable
478 .Va taskqueue_fast .
479 .Pp
480 The software interrupt queues can be used,
481 for instance, for implementing interrupt handlers which must perform a
482 significant amount of processing in the handler.
483 The hardware interrupt handler would perform minimal processing of the
484 interrupt and then enqueue a task to finish the work.
485 This reduces to a minimum
486 the amount of time spent with interrupts disabled.
487 .Pp
488 The thread queue can be used, for instance, by interrupt level routines
489 that need to call kernel functions that do things that can only be done
490 from a thread context.
491 (e.g., call malloc with the M_WAITOK flag.)
492 .Pp
493 Note that tasks queued on shared taskqueues such as
494 .Va taskqueue_swi
495 may be delayed an indeterminate amount of time before execution.
496 If queueing delays cannot be tolerated then a private taskqueue should
497 be created with a dedicated processing thread.
498 .Sh SEE ALSO
499 .Xr ithread 9 ,
500 .Xr kthread 9 ,
501 .Xr swi 9
502 .Sh HISTORY
503 This interface first appeared in
504 .Fx 5.0 .
505 There is a similar facility called work_queue in the Linux kernel.
506 .Sh AUTHORS
507 This manual page was written by
508 .An Doug Rabson .