]> CyberLeo.Net >> Repos - FreeBSD/stable/8.git/blob - share/man/man9/taskqueue.9
MFC r362623:
[FreeBSD/stable/8.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 24, 2014
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 .Ed
56 .Ft struct taskqueue *
57 .Fn taskqueue_create "const char *name" "int mflags" "taskqueue_enqueue_fn enqueue" "void *context"
58 .Ft struct taskqueue *
59 .Fn taskqueue_create_fast "const char *name" "int mflags" "taskqueue_enqueue_fn enqueue" "void *context"
60 .Ft void
61 .Fn taskqueue_free "struct taskqueue *queue"
62 .Ft int
63 .Fn taskqueue_enqueue "struct taskqueue *queue" "struct task *task"
64 .Ft int
65 .Fn taskqueue_enqueue_fast "struct taskqueue *queue" "struct task *task"
66 .Ft void
67 .Fn taskqueue_run "struct taskqueue *queue"
68 .Ft void
69 .Fn taskqueue_run_fast "struct taskqueue *queue"
70 .Ft void
71 .Fn taskqueue_drain "struct taskqueue *queue" "struct task *task"
72 .Ft void
73 .Fn taskqueue_drain_all "struct taskqueue *queue"
74 .Ft void
75 .Fn taskqueue_block "struct taskqueue *queue"
76 .Ft void
77 .Fn taskqueue_unblock "struct taskqueue *queue"
78 .Ft int
79 .Fn taskqueue_member "struct taskqueue *queue" "struct thread *td"
80 .Fn TASK_INIT "struct task *task" "int priority" "task_fn_t *func" "void *context"
81 .Fn TASK_INITIALIZER "int priority" "task_fn_t func" "void *context"
82 .Fn TASKQUEUE_DECLARE "name"
83 .Fn TASKQUEUE_DEFINE "name" "taskqueue_enqueue_fn enqueue" "void *context" "init"
84 .Fn TASKQUEUE_FAST_DEFINE "name" "taskqueue_enqueue_fn enqueue" "void *context" "init"
85 .Fn TASKQUEUE_DEFINE_THREAD "name"
86 .Fn TASKQUEUE_FAST_DEFINE_THREAD "name"
87 .Sh DESCRIPTION
88 These functions provide a simple interface for asynchronous execution
89 of code.
90 .Pp
91 The function
92 .Fn taskqueue_create
93 is used to create new queues.
94 The arguments to
95 .Fn taskqueue_create
96 include a name that should be unique,
97 a set of
98 .Xr malloc 9
99 flags that specify whether the call to
100 .Fn malloc
101 is allowed to sleep,
102 a function that is called from
103 .Fn taskqueue_enqueue
104 when a task is added to the queue,
105 and a pointer to the memory location where the identity of the
106 thread that services the queue is recorded.
107 .\" XXX The rest of the sentence gets lots in relation to the first part.
108 The function called from
109 .Fn taskqueue_enqueue
110 must arrange for the queue to be processed
111 (for instance by scheduling a software interrupt or waking a kernel
112 thread).
113 The memory location where the thread identity is recorded is used
114 to signal the service thread(s) to terminate--when this value is set to
115 zero and the thread is signaled it will terminate.
116 If the queue is intended for use in fast interrupt handlers 
117 .Fn taskqueue_create_fast 
118 should be used in place of
119 .Fn taskqueue_create .
120 .Pp
121 The function
122 .Fn taskqueue_free
123 should be used to free the memory used by the queue.
124 Any tasks that are on the queue will be executed at this time after
125 which the thread servicing the queue will be signaled that it should exit.
126 .Pp
127 To add a task to the list of tasks queued on a taskqueue, call
128 .Fn taskqueue_enqueue
129 with pointers to the queue and task.
130 If the task's
131 .Va ta_pending
132 field is non-zero,
133 then it is simply incremented to reflect the number of times the task
134 was enqueued, up to a cap of USHRT_MAX.
135 Otherwise,
136 the task is added to the list before the first task which has a lower
137 .Va ta_priority
138 value or at the end of the list if no tasks have a lower priority.
139 Enqueueing a task does not perform any memory allocation which makes
140 it suitable for calling from an interrupt handler.
141 This function will return
142 .Er EPIPE
143 if the queue is being freed.
144 .Pp
145 The function
146 .Fn taskqueue_enqueue_fast
147 should be used in place of
148 .Fn taskqueue_enqueue
149 when the enqueuing must happen from a fast interrupt handler.
150 This method uses spin locks to avoid the possibility of sleeping in the fast
151 interrupt context.
152 .Pp
153 To execute all the tasks on a queue,
154 call
155 .Fn taskqueue_run
156 or
157 .Fn taskqueue_run_fast
158 depending on the flavour of the queue.
159 When a task is executed,
160 first it is removed from the queue,
161 the value of
162 .Va ta_pending
163 is recorded and then the field is zeroed.
164 The function
165 .Va ta_func
166 from the task structure is called with the value of the field
167 .Va ta_context
168 as its first argument
169 and the value of
170 .Va ta_pending
171 as its second argument.
172 After the function
173 .Va ta_func
174 returns,
175 .Xr wakeup 9
176 is called on the task pointer passed to
177 .Fn taskqueue_enqueue .
178 .Pp
179 The
180 .Fn taskqueue_drain
181 function is used to wait for the task to finish.
182 There is no guarantee that the task will not be
183 enqueued after call to
184 .Fn taskqueue_drain .
185 If the caller wants to put the task into a known state,
186 then before calling
187 .Fn taskqueue_drain
188 the caller should use out-of-band means to ensure that the task
189 would not be enqueued.
190 For example, if the task is enqueued by an interrupt filter, then
191 the interrupt could be disabled.
192 .Pp
193 The
194 .Fn taskqueue_drain_all
195 function is used to wait for all pending and running tasks that
196 are enqueued on the taskqueue to finish.
197 The caller must arrange that the tasks are not re-enqueued.
198 Note that
199 .Fn taskqueue_drain_all
200 currently does not handle tasks with delayed enqueueing.
201 .Pp
202 The
203 .Fn taskqueue_block
204 function blocks the taskqueue.
205 It prevents any enqueued but not running tasks from being executed.
206 Future calls to
207 .Fn taskqueue_enqueue
208 will enqueue tasks, but the tasks will not be run until
209 .Fn taskqueue_unblock
210 is called.
211 Please note that
212 .Fn taskqueue_block
213 does not wait for any currently running tasks to finish.
214 Thus, the
215 .Fn taskqueue_block
216 does not provide a guarantee that
217 .Fn taskqueue_run
218 is not running after
219 .Fn taskqueue_block
220 returns, but it does provide a guarantee that
221 .Fn taskqueue_run
222 will not be called again
223 until
224 .Fn taskqueue_unblock
225 is called.
226 If the caller requires a guarantee that
227 .Fn taskqueue_run
228 is not running, then this must be arranged by the caller.
229 Note that if
230 .Fn taskqueue_drain
231 is called on a task that is enqueued on a taskqueue that is blocked by
232 .Fn taskqueue_block ,
233 then
234 .Fn taskqueue_drain
235 can not return until the taskqueue is unblocked.
236 This can result in a deadlock if the thread blocked in
237 .Fn taskqueue_drain
238 is the thread that is supposed to call
239 .Fn taskqueue_unblock .
240 Thus, use of
241 .Fn taskqueue_drain
242 after
243 .Fn taskqueue_block
244 is discouraged, because the state of the task can not be known in advance.
245 The same caveat applies to
246 .Fn taskqueue_drain_all .
247 .Pp
248 The
249 .Fn taskqueue_unblock
250 function unblocks the previously blocked taskqueue.
251 All enqueued tasks can be run after this call.
252 .Pp
253 The
254 .Fn taskqueue_member
255 function returns
256 .No 1
257 if the given thread
258 .Fa td
259 is part of the given taskqeueue
260 .Fa queue
261 and
262 .No 0
263 otherwise.
264 .Pp
265 A convenience macro,
266 .Fn TASK_INIT "task" "priority" "func" "context"
267 is provided to initialise a
268 .Va task
269 structure.
270 The
271 .Fn TASK_INITIALIZER
272 macro generates an initializer for a task structure.
273 The values of
274 .Va priority ,
275 .Va func ,
276 and
277 .Va context
278 are simply copied into the task structure fields and the
279 .Va ta_pending
280 field is cleared.
281 .Pp
282 Five macros
283 .Fn TASKQUEUE_DECLARE "name" ,
284 .Fn TASKQUEUE_DEFINE "name" "enqueue" "context" "init" ,
285 .Fn TASKQUEUE_FAST_DEFINE "name" "enqueue" "context" "init" ,
286 and
287 .Fn TASKQUEUE_DEFINE_THREAD "name"
288 .Fn TASKQUEUE_FAST_DEFINE_THREAD "name"
289 are used to declare a reference to a global queue, to define the
290 implementation of the queue, and declare a queue that uses its own thread.
291 The
292 .Fn TASKQUEUE_DEFINE
293 macro arranges to call
294 .Fn taskqueue_create
295 with the values of its
296 .Va name ,
297 .Va enqueue
298 and
299 .Va context
300 arguments during system initialisation.
301 After calling
302 .Fn taskqueue_create ,
303 the
304 .Va init
305 argument to the macro is executed as a C statement,
306 allowing any further initialisation to be performed
307 (such as registering an interrupt handler etc.)
308 .Pp
309 The
310 .Fn TASKQUEUE_DEFINE_THREAD
311 macro defines a new taskqueue with its own kernel thread to serve tasks.
312 The variable
313 .Vt struct taskqueue *taskqueue_name
314 is used to enqueue tasks onto the queue.
315 .Pp
316 .Fn TASKQUEUE_FAST_DEFINE
317 and 
318 .Fn TASKQUEUE_FAST_DEFINE_THREAD
319 act just like 
320 .Fn TASKQUEUE_DEFINE
321 and
322 .Fn TASKQUEUE_DEFINE_THREAD
323 respectively but taskqueue is created with
324 .Fn taskqueue_create_fast .
325 .Ss Predefined Task Queues
326 The system provides four global taskqueues,
327 .Va taskqueue_fast ,
328 .Va taskqueue_swi ,
329 .Va taskqueue_swi_giant ,
330 and
331 .Va taskqueue_thread .
332 The
333 .Va taskqueue_fast
334 queue is for swi handlers dispatched from fast interrupt handlers,
335 where sleep mutexes cannot be used.
336 The swi taskqueues are run via a software interrupt mechanism.
337 The
338 .Va taskqueue_swi
339 queue runs without the protection of the
340 .Va Giant
341 kernel lock, and the
342 .Va taskqueue_swi_giant
343 queue runs with the protection of the
344 .Va Giant
345 kernel lock.
346 The thread taskqueue
347 .Va taskqueue_thread
348 runs in a kernel thread context, and tasks run from this thread do
349 not run under the
350 .Va Giant
351 kernel lock.
352 If the caller wants to run under
353 .Va Giant ,
354 he should explicitly acquire and release
355 .Va Giant
356 in his taskqueue handler routine.
357 .Pp
358 To use these queues,
359 call
360 .Fn taskqueue_enqueue
361 with the value of the global taskqueue variable for the queue you wish to
362 use
363 .Va ( taskqueue_swi ,
364 .Va taskqueue_swi_giant ,
365 or
366 .Va taskqueue_thread ) .
367 Use
368 .Fn taskqueue_enqueue_fast
369 for the global taskqueue variable
370 .Va taskqueue_fast .
371 .Pp
372 The software interrupt queues can be used,
373 for instance, for implementing interrupt handlers which must perform a
374 significant amount of processing in the handler.
375 The hardware interrupt handler would perform minimal processing of the
376 interrupt and then enqueue a task to finish the work.
377 This reduces to a minimum
378 the amount of time spent with interrupts disabled.
379 .Pp
380 The thread queue can be used, for instance, by interrupt level routines
381 that need to call kernel functions that do things that can only be done
382 from a thread context.
383 (e.g., call malloc with the M_WAITOK flag.)
384 .Pp
385 Note that tasks queued on shared taskqueues such as
386 .Va taskqueue_swi
387 may be delayed an indeterminate amount of time before execution.
388 If queueing delays cannot be tolerated then a private taskqueue should
389 be created with a dedicated processing thread.
390 .Sh SEE ALSO
391 .Xr ithread 9 ,
392 .Xr kthread 9 ,
393 .Xr swi 9
394 .Sh HISTORY
395 This interface first appeared in
396 .Fx 5.0 .
397 There is a similar facility called tqueue in the Linux kernel.
398 .Sh AUTHORS
399 This manual page was written by
400 .An Doug Rabson .