xref: /dflybsd-src/share/man/man9/taskqueue.9 (revision a0d617553c785d5636a94593934080747a1dbca6)
1a247c996SSascha Wildner.\"
2a247c996SSascha Wildner.\" Copyright (c) 2000 Doug Rabson
3a247c996SSascha Wildner.\"
4a247c996SSascha Wildner.\" All rights reserved.
5a247c996SSascha Wildner.\"
6a247c996SSascha Wildner.\" This program is free software.
7a247c996SSascha Wildner.\"
8a247c996SSascha Wildner.\" Redistribution and use in source and binary forms, with or without
9a247c996SSascha Wildner.\" modification, are permitted provided that the following conditions
10a247c996SSascha Wildner.\" are met:
11a247c996SSascha Wildner.\" 1. Redistributions of source code must retain the above copyright
12a247c996SSascha Wildner.\"    notice, this list of conditions and the following disclaimer.
13a247c996SSascha Wildner.\" 2. Redistributions in binary form must reproduce the above copyright
14a247c996SSascha Wildner.\"    notice, this list of conditions and the following disclaimer in the
15a247c996SSascha Wildner.\"    documentation and/or other materials provided with the distribution.
16a247c996SSascha Wildner.\"
17a247c996SSascha Wildner.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
18a247c996SSascha Wildner.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19a247c996SSascha Wildner.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20a247c996SSascha Wildner.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
21a247c996SSascha Wildner.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22a247c996SSascha Wildner.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23a247c996SSascha Wildner.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24a247c996SSascha Wildner.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25a247c996SSascha Wildner.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26a247c996SSascha Wildner.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27a247c996SSascha Wildner.\"
28a247c996SSascha Wildner.\" $FreeBSD: src/share/man/man9/taskqueue.9,v 1.21 2007/07/09 06:24:10 jmg Exp $
2987909ed3SSascha Wildner.\" $DragonFly: src/share/man/man9/taskqueue.9,v 1.2 2007/11/07 21:38:00 swildner Exp $
30a247c996SSascha Wildner.\"
31a247c996SSascha Wildner.Dd August 10, 2007
32a247c996SSascha Wildner.Dt TASKQUEUE 9
33a247c996SSascha Wildner.Os
34a247c996SSascha Wildner.Sh NAME
35a247c996SSascha Wildner.Nm taskqueue_create ,
36a247c996SSascha Wildner.Nm taskqueue_free ,
37a247c996SSascha Wildner.Nm taskqueue_find ,
38a247c996SSascha Wildner.Nm taskqueue_enqueue ,
39a247c996SSascha Wildner.Nm taskqueue_run ,
40a247c996SSascha Wildner.Nm TASK_INIT ,
41a247c996SSascha Wildner.Nm TASKQUEUE_DECLARE ,
42a247c996SSascha Wildner.Nm TASKQUEUE_DEFINE
43a247c996SSascha Wildner.Nd asynchronous task execution
44a247c996SSascha Wildner.Sh SYNOPSIS
45a247c996SSascha Wildner.In sys/param.h
46a247c996SSascha Wildner.In sys/kernel.h
47a247c996SSascha Wildner.In sys/malloc.h
48a247c996SSascha Wildner.In sys/queue.h
49a247c996SSascha Wildner.In sys/taskqueue.h
50a247c996SSascha Wildner.Bd -literal
51a247c996SSascha Wildnertypedef void (*task_fn_t)(void *context, int pending);
52a247c996SSascha Wildner
53a247c996SSascha Wildnertypedef void (*taskqueue_enqueue_fn)(void *context);
54a247c996SSascha Wildner
55a247c996SSascha Wildnerstruct task {
56a247c996SSascha Wildner	STAILQ_ENTRY(task)	ta_link;	/* link for queue */
57a247c996SSascha Wildner	int			ta_pending;	/* count times queued */
58a247c996SSascha Wildner	int			ta_priority;	/* priority of task in queue */
59a247c996SSascha Wildner	task_fn_t		ta_func;	/* task handler */
60a247c996SSascha Wildner	void			*ta_context;	/* argument for handler */
61a247c996SSascha Wildner};
62a247c996SSascha Wildner.Ed
63a247c996SSascha Wildner.Ft struct taskqueue *
64a247c996SSascha Wildner.Fn taskqueue_create "const char *name" "int mflags" "taskqueue_enqueue_fn enqueue" "void *context"
65a247c996SSascha Wildner.Ft void
66a247c996SSascha Wildner.Fn taskqueue_free "struct taskqueue *queue"
67a247c996SSascha Wildner.Ft struct taskqueue *
68a247c996SSascha Wildner.Fn taskqueue_find "const char *name"
69a247c996SSascha Wildner.Ft int
70a247c996SSascha Wildner.Fn taskqueue_enqueue "struct taskqueue *queue" "struct task *task"
71a247c996SSascha Wildner.Ft void
72a247c996SSascha Wildner.Fn taskqueue_run "struct taskqueue *queue"
73*a0d61755SAlex Hornung.Ft void
74*a0d61755SAlex Hornung.Fn taskqueue_drain "struct taskqueue *queue" "struct task *task"
75*a0d61755SAlex Hornung.Ft void
76*a0d61755SAlex Hornung.Fn taskqueue_block "struct taskqueue *queue"
77*a0d61755SAlex Hornung.Ft void
78*a0d61755SAlex Hornung.Fn taskqueue_unblock "struct taskqueue *queue"
79*a0d61755SAlex Hornung.Ft int
80*a0d61755SAlex Hornung.Fn taskqueue_start_threads "struct taskqueue **tqp" "int count" "int pri" "const char *fmt" "..."
81a247c996SSascha Wildner.Fn TASK_INIT "struct task *task" "int priority" "task_fn_t *func" "void *context"
82a247c996SSascha Wildner.Fn TASKQUEUE_DECLARE "name"
83a247c996SSascha Wildner.Fn TASKQUEUE_DEFINE "name" "taskqueue_enqueue_fn enqueue" "void *context" "init"
84a247c996SSascha Wildner.Sh DESCRIPTION
85a247c996SSascha WildnerThese functions provide a simple interface for asynchronous execution
86a247c996SSascha Wildnerof code.
87a247c996SSascha Wildner.Pp
88a247c996SSascha WildnerThe function
89a247c996SSascha Wildner.Fn taskqueue_create
90a247c996SSascha Wildneris used to create new queues.
91a247c996SSascha WildnerThe arguments to
92a247c996SSascha Wildner.Fn taskqueue_create
93a247c996SSascha Wildnerinclude a name that should be unique,
94a247c996SSascha Wildnera set of
9587909ed3SSascha Wildner.Xr kmalloc 9
96a247c996SSascha Wildnerflags that specify whether the call to
97a247c996SSascha Wildner.Fn malloc
98a247c996SSascha Wildneris allowed to sleep,
99a247c996SSascha Wildnerand a function which is called from
100a247c996SSascha Wildner.Fn taskqueue_enqueue
101a247c996SSascha Wildnerwhen a task is added to the queue
102a247c996SSascha Wildner.\" XXX	The rest of the sentence gets lots in relation to the first part.
103a247c996SSascha Wildnerto allow the queue to arrange to be run later
104a247c996SSascha Wildner(for instance by scheduling a software interrupt or waking a kernel
105a247c996SSascha Wildnerthread).
106a247c996SSascha Wildner.Pp
107a247c996SSascha WildnerThe function
108a247c996SSascha Wildner.Fn taskqueue_free
109a247c996SSascha Wildnershould be used to remove the queue from the global list of queues
110a247c996SSascha Wildnerand free the memory used by the queue.
111a247c996SSascha WildnerAny tasks that are on the queue will be executed at this time.
112a247c996SSascha Wildner.Pp
113a247c996SSascha WildnerThe system maintains a list of all queues which can be searched using
114a247c996SSascha Wildner.Fn taskqueue_find .
115a247c996SSascha WildnerThe first queue whose name matches is returned, otherwise
116a247c996SSascha Wildner.Dv NULL .
117a247c996SSascha Wildner.Pp
118a247c996SSascha WildnerTo add a task to the list of tasks queued on a taskqueue, call
119a247c996SSascha Wildner.Fn taskqueue_enqueue
120a247c996SSascha Wildnerwith pointers to the queue and task.
121a247c996SSascha WildnerIf the task's
122a247c996SSascha Wildner.Fa ta_pending
123a247c996SSascha Wildnerfield is non-zero,
124a247c996SSascha Wildnerthen it is simply incremented to reflect the number of times the task
125a247c996SSascha Wildnerwas enqueued.
126a247c996SSascha WildnerOtherwise,
127a247c996SSascha Wildnerthe task is added to the list before the first task which has a lower
128a247c996SSascha Wildner.Fa ta_priority
129a247c996SSascha Wildnervalue or at the end of the list if no tasks have a lower priority.
130a247c996SSascha WildnerEnqueueing a task does not perform any memory allocation which makes
131a247c996SSascha Wildnerit suitable for calling from an interrupt handler.
132a247c996SSascha WildnerThis function will return
133a247c996SSascha Wildner.Er EPIPE
134a247c996SSascha Wildnerif the queue is being freed.
135a247c996SSascha Wildner.Pp
136a247c996SSascha WildnerTo execute all the tasks on a queue,
137a247c996SSascha Wildnercall
138a247c996SSascha Wildner.Fn taskqueue_run .
139a247c996SSascha WildnerWhen a task is executed,
140a247c996SSascha Wildnerfirst it is removed from the queue,
141a247c996SSascha Wildnerthe value of
142a247c996SSascha Wildner.Fa ta_pending
143a247c996SSascha Wildneris recorded and then the field is zeroed.
144a247c996SSascha WildnerThe function
145a247c996SSascha Wildner.Fa ta_func
146a247c996SSascha Wildnerfrom the task structure is called with the value of the field
147a247c996SSascha Wildner.Fa ta_context
148a247c996SSascha Wildneras its first argument
149a247c996SSascha Wildnerand the value of
150a247c996SSascha Wildner.Fa ta_pending
151a247c996SSascha Wildneras its second argument.
152a247c996SSascha Wildner.Pp
153*a0d61755SAlex HornungThe
154*a0d61755SAlex Hornung.Fn taskqueue_drain
155*a0d61755SAlex Hornungfunction is used to wait for the task to finish.
156*a0d61755SAlex HornungThere is no guarantee that the task will not be
157*a0d61755SAlex Hornungenqueued after call to
158*a0d61755SAlex Hornung.Fn taskqueue_drain .
159*a0d61755SAlex Hornung.Pp
160*a0d61755SAlex HornungThe
161*a0d61755SAlex Hornung.Fn taskqueue_block
162*a0d61755SAlex Hornungfunction is used to block a taskqueue. When a taskqueue
163*a0d61755SAlex Hornungis blocked, calls to enqueue will still enqueue tasks but
164*a0d61755SAlex Hornungthey will not be run until the taskqueue is unblocked by
165*a0d61755SAlex Hornungcalling
166*a0d61755SAlex Hornung.Fn taskqueue_unblock .
167*a0d61755SAlex Hornung.Pp
168*a0d61755SAlex HornungThe
169*a0d61755SAlex Hornung.Fn taskqueue_start_threads
170*a0d61755SAlex Hornungfunction is used to create and start
171*a0d61755SAlex Hornung.Fa count
172*a0d61755SAlex Hornungdedicated threads for the taskqueue specified by
173*a0d61755SAlex Hornung.Fa tqp .
174*a0d61755SAlex HornungThese threads will be created with the priority specified by
175*a0d61755SAlex Hornung.Fa pri
176*a0d61755SAlex Hornungand the name given by
177*a0d61755SAlex Hornung.Fa fmt
178*a0d61755SAlex Hornungwith _N appended to it, where N is the number of the thread.
179*a0d61755SAlex HornungThe taskqueue specified by
180*a0d61755SAlex Hornung.Fa tqp
181*a0d61755SAlex Hornungmust be created previously by calling
182*a0d61755SAlex Hornung.Fn taskqueue_create
183*a0d61755SAlex Hornungwith the argument
184*a0d61755SAlex Hornung.Fa enqueue
185*a0d61755SAlex Hornungset to
186*a0d61755SAlex Hornung.Fa taskqueue_thread_enqueue .
187*a0d61755SAlex Hornung.Pp
188a247c996SSascha WildnerA convenience macro,
189a247c996SSascha Wildner.Fn TASK_INIT
190a247c996SSascha Wildneris provided to initialise a
191a247c996SSascha Wildner.Vt task
192a247c996SSascha Wildnerstructure.
193a247c996SSascha WildnerThe values of
194a247c996SSascha Wildner.Fa priority ,
195a247c996SSascha Wildner.Fa func ,
196a247c996SSascha Wildnerand
197a247c996SSascha Wildner.Fa context
198a247c996SSascha Wildnerare simply copied into the task structure fields and the
199a247c996SSascha Wildner.Fa ta_pending
200a247c996SSascha Wildnerfield is cleared.
201a247c996SSascha Wildner.Pp
202a247c996SSascha WildnerTwo macros,
203a247c996SSascha Wildner.Fn TASKQUEUE_DECLARE
204a247c996SSascha Wildnerand
205a247c996SSascha Wildner.Fn TASKQUEUE_DEFINE
206a247c996SSascha Wildnerare used to declare a reference to a global queue,
207a247c996SSascha Wildnerand to define the implementation of the queue.
208a247c996SSascha WildnerThe
209a247c996SSascha Wildner.Fn TASKQUEUE_DEFINE
210a247c996SSascha Wildnermacro arranges to call
211a247c996SSascha Wildner.Fn taskqueue_create
212a247c996SSascha Wildnerwith the values of its
213a247c996SSascha Wildner.Fa name ,
214a247c996SSascha Wildner.Fa enqueue
215a247c996SSascha Wildnerand
216a247c996SSascha Wildner.Fa context
217a247c996SSascha Wildnerarguments during system initialisation.
218a247c996SSascha WildnerAfter calling
219a247c996SSascha Wildner.Fn taskqueue_create ,
220a247c996SSascha Wildnerthe
221a247c996SSascha Wildner.Fa init
222a247c996SSascha Wildnerargument to the macro is executed as a C statement,
223a247c996SSascha Wildnerallowing any further initialisation to be performed
224a247c996SSascha Wildner(such as registering an interrupt handler etc.)
225a247c996SSascha Wildner.Pp
226*a0d61755SAlex HornungThe system provides two global taskqueues,
227a247c996SSascha Wildner.Va taskqueue_swi ,
228*a0d61755SAlex Hornung.Va taskqueue_swi_mp ,
229*a0d61755SAlex Hornungwhich are run via a software interrupt mechanism.
230*a0d61755SAlex HornungTo use these queues, call
231a247c996SSascha Wildner.Fn taskqueue_enqueue
232a247c996SSascha Wildnerwith the value of the global variable
233*a0d61755SAlex Hornung.Va taskqueue_swi or
234*a0d61755SAlex Hornung.Va taskqueue_swi_mp .
235a247c996SSascha Wildner.Pp
236*a0d61755SAlex HornungWhile
237*a0d61755SAlex Hornung.Va taskqueue_swi
238*a0d61755SAlex Hornungacquires the mplock for its tasks,
239*a0d61755SAlex Hornung.Va taskqueue_swi_mp
240*a0d61755SAlex Hornungis intended for mpsafe tasks and no mplock will be acquired for them.
241*a0d61755SAlex HornungThese queues can be used,
242a247c996SSascha Wildnerfor instance, for implementing interrupt handlers which must perform a
243a247c996SSascha Wildnersignificant amount of processing in the handler.
244a247c996SSascha WildnerThe hardware interrupt handler would perform minimal processing of the
245a247c996SSascha Wildnerinterrupt and then enqueue a task to finish the work.
246a247c996SSascha WildnerThis reduces to a minimum
247a247c996SSascha Wildnerthe amount of time spent with interrupts disabled.
248a247c996SSascha Wildner.\".Sh SEE ALSO
249a247c996SSascha Wildner.\".Xr ithread 9 ,
250a247c996SSascha Wildner.\".Xr kthread 9 ,
251a247c996SSascha Wildner.\".Xr swi 9
252a247c996SSascha Wildner.Sh HISTORY
253a247c996SSascha WildnerThis interface first appeared in
254a247c996SSascha Wildner.Fx 5.0 .
255a247c996SSascha WildnerThere is a similar facility called tqueue in the Linux kernel.
256a247c996SSascha Wildner.Sh AUTHORS
257a247c996SSascha WildnerThis manual page was written by
258a247c996SSascha Wildner.An Doug Rabson .
259