]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - share/man/man9/taskqueue.9
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.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 August 18, 2009
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 int
73 .Fn taskqueue_member "struct taskqueue *queue" "struct thread *td"
74 .Fn TASK_INIT "struct task *task" "int priority" "task_fn_t *func" "void *context"
75 .Fn TASKQUEUE_DECLARE "name"
76 .Fn TASKQUEUE_DEFINE "name" "taskqueue_enqueue_fn enqueue" "void *context" "init"
77 .Fn TASKQUEUE_FAST_DEFINE "name" "taskqueue_enqueue_fn enqueue" "void *context" "init"
78 .Fn TASKQUEUE_DEFINE_THREAD "name"
79 .Fn TASKQUEUE_FAST_DEFINE_THREAD "name"
80 .Sh DESCRIPTION
81 These functions provide a simple interface for asynchronous execution
82 of code.
83 .Pp
84 The function
85 .Fn taskqueue_create
86 is used to create new queues.
87 The arguments to
88 .Fn taskqueue_create
89 include a name that should be unique,
90 a set of
91 .Xr malloc 9
92 flags that specify whether the call to
93 .Fn malloc
94 is allowed to sleep,
95 a function that is called from
96 .Fn taskqueue_enqueue
97 when a task is added to the queue,
98 and a pointer to the memory location where the identity of the
99 thread that services the queue is recorded.
100 .\" XXX The rest of the sentence gets lots in relation to the first part.
101 The function called from
102 .Fn taskqueue_enqueue
103 must arrange for the queue to be processed
104 (for instance by scheduling a software interrupt or waking a kernel
105 thread).
106 The memory location where the thread identity is recorded is used
107 to signal the service thread(s) to terminate--when this value is set to
108 zero and the thread is signaled it will terminate.
109 If the queue is intended for use in fast interrupt handlers 
110 .Fn taskqueue_create_fast 
111 should be used in place of
112 .Fn taskqueue_create .
113 .Pp
114 The function
115 .Fn taskqueue_free
116 should be used to free the memory used by the queue.
117 Any tasks that are on the queue will be executed at this time after
118 which the thread servicing the queue will be signaled that it should exit.
119 .Pp
120 To add a task to the list of tasks queued on a taskqueue, call
121 .Fn taskqueue_enqueue
122 with pointers to the queue and task.
123 If the task's
124 .Va ta_pending
125 field is non-zero,
126 then it is simply incremented to reflect the number of times the task
127 was enqueued.
128 Otherwise,
129 the task is added to the list before the first task which has a lower
130 .Va ta_priority
131 value or at the end of the list if no tasks have a lower priority.
132 Enqueueing a task does not perform any memory allocation which makes
133 it suitable for calling from an interrupt handler.
134 This function will return
135 .Er EPIPE
136 if the queue is being freed.
137 .Pp
138 The function
139 .Fn taskqueue_enqueue_fast
140 should be used in place of
141 .Fn taskqueue_enqueue
142 when the enqueuing must happen from a fast interrupt handler.
143 This method uses spin locks to avoid the possibility of sleeping in the fast
144 interrupt context.
145 .Pp
146 To execute all the tasks on a queue,
147 call
148 .Fn taskqueue_run
149 or
150 .Fn taskqueue_run_fast
151 depending on the flavour of the queue.
152 When a task is executed,
153 first it is removed from the queue,
154 the value of
155 .Va ta_pending
156 is recorded and then the field is zeroed.
157 The function
158 .Va ta_func
159 from the task structure is called with the value of the field
160 .Va ta_context
161 as its first argument
162 and the value of
163 .Va ta_pending
164 as its second argument.
165 After the function
166 .Va ta_func
167 returns,
168 .Xr wakeup 9
169 is called on the task pointer passed to
170 .Fn taskqueue_enqueue .
171 .Pp
172 The
173 .Fn taskqueue_drain
174 function is used to wait for the task to finish.
175 There is no guarantee that the task will not be
176 enqueued after call to
177 .Fn taskqueue_drain .
178 .Pp
179 The
180 .Fn taskqueue_member
181 function returns
182 .No 1
183 if the given thread
184 .Fa td
185 is part of the given taskqeueue
186 .Fa queue
187 and
188 .No 0
189 otherwise.
190 .Pp
191 A convenience macro,
192 .Fn TASK_INIT "task" "priority" "func" "context"
193 is provided to initialise a
194 .Va task
195 structure.
196 The values of
197 .Va priority ,
198 .Va func ,
199 and
200 .Va context
201 are simply copied into the task structure fields and the
202 .Va ta_pending
203 field is cleared.
204 .Pp
205 Five macros
206 .Fn TASKQUEUE_DECLARE "name" ,
207 .Fn TASKQUEUE_DEFINE "name" "enqueue" "context" "init" ,
208 .Fn TASKQUEUE_FAST_DEFINE "name" "enqueue" "context" "init" ,
209 and
210 .Fn TASKQUEUE_DEFINE_THREAD "name"
211 .Fn TASKQUEUE_FAST_DEFINE_THREAD "name"
212 are used to declare a reference to a global queue, to define the
213 implementation of the queue, and declare a queue that uses its own thread.
214 The
215 .Fn TASKQUEUE_DEFINE
216 macro arranges to call
217 .Fn taskqueue_create
218 with the values of its
219 .Va name ,
220 .Va enqueue
221 and
222 .Va context
223 arguments during system initialisation.
224 After calling
225 .Fn taskqueue_create ,
226 the
227 .Va init
228 argument to the macro is executed as a C statement,
229 allowing any further initialisation to be performed
230 (such as registering an interrupt handler etc.)
231 .Pp
232 The
233 .Fn TASKQUEUE_DEFINE_THREAD
234 macro defines a new taskqueue with its own kernel thread to serve tasks.
235 The variable
236 .Vt struct taskqueue *taskqueue_name
237 is used to enqueue tasks onto the queue.
238 .Pp
239 .Fn TASKQUEUE_FAST_DEFINE
240 and 
241 .Fn TASKQUEUE_FAST_DEFINE_THREAD
242 act just like 
243 .Fn TASKQUEUE_DEFINE
244 and
245 .Fn TASKQUEUE_DEFINE_THREAD
246 respectively but taskqueue is created with
247 .Fn taskqueue_create_fast .
248 .Ss Predefined Task Queues
249 The system provides four global taskqueues,
250 .Va taskqueue_fast ,
251 .Va taskqueue_swi ,
252 .Va taskqueue_swi_giant ,
253 and
254 .Va taskqueue_thread .
255 The
256 .Va taskqueue_fast
257 queue is for swi handlers dispatched from fast interrupt handlers,
258 where sleep mutexes cannot be used.
259 The swi taskqueues are run via a software interrupt mechanism.
260 The
261 .Va taskqueue_swi
262 queue runs without the protection of the
263 .Va Giant
264 kernel lock, and the
265 .Va taskqueue_swi_giant
266 queue runs with the protection of the
267 .Va Giant
268 kernel lock.
269 The thread taskqueue
270 .Va taskqueue_thread
271 runs in a kernel thread context, and tasks run from this thread do
272 not run under the
273 .Va Giant
274 kernel lock.
275 If the caller wants to run under
276 .Va Giant ,
277 he should explicitly acquire and release
278 .Va Giant
279 in his taskqueue handler routine.
280 .Pp
281 To use these queues,
282 call
283 .Fn taskqueue_enqueue
284 with the value of the global taskqueue variable for the queue you wish to
285 use
286 .Va ( taskqueue_swi ,
287 .Va taskqueue_swi_giant ,
288 or
289 .Va taskqueue_thread ) .
290 Use
291 .Fn taskqueue_enqueue_fast
292 for the global taskqueue variable
293 .Va taskqueue_fast .
294 .Pp
295 The software interrupt queues can be used,
296 for instance, for implementing interrupt handlers which must perform a
297 significant amount of processing in the handler.
298 The hardware interrupt handler would perform minimal processing of the
299 interrupt and then enqueue a task to finish the work.
300 This reduces to a minimum
301 the amount of time spent with interrupts disabled.
302 .Pp
303 The thread queue can be used, for instance, by interrupt level routines
304 that need to call kernel functions that do things that can only be done
305 from a thread context.
306 (e.g., call malloc with the M_WAITOK flag.)
307 .Pp
308 Note that tasks queued on shared taskqueues such as
309 .Va taskqueue_swi
310 may be delayed an indeterminate amount of time before execution.
311 If queueing delays cannot be tolerated then a private taskqueue should
312 be created with a dedicated processing thread.
313 .Sh SEE ALSO
314 .Xr ithread 9 ,
315 .Xr kthread 9 ,
316 .Xr swi 9
317 .Sh HISTORY
318 This interface first appeared in
319 .Fx 5.0 .
320 There is a similar facility called tqueue in the Linux kernel.
321 .Sh AUTHORS
322 This manual page was written by
323 .An Doug Rabson .