xref: /dflybsd-src/share/man/man9/taskqueue.9 (revision cb24fcd4e40030ed3e6d1d9a4afcf351846c67d0)
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 $
29a247c996SSascha Wildner.\"
30*cb24fcd4SSascha Wildner.Dd October 2, 2009
31a247c996SSascha Wildner.Dt TASKQUEUE 9
32a247c996SSascha Wildner.Os
33a247c996SSascha Wildner.Sh NAME
34*cb24fcd4SSascha Wildner.Nm taskqueue_block ,
35a247c996SSascha Wildner.Nm taskqueue_create ,
36*cb24fcd4SSascha Wildner.Nm tastqueue_drain ,
37*cb24fcd4SSascha Wildner.Nm taskqueue_enqueue ,
38a247c996SSascha Wildner.Nm taskqueue_free ,
39a247c996SSascha Wildner.Nm taskqueue_find ,
40a247c996SSascha Wildner.Nm taskqueue_run ,
41*cb24fcd4SSascha Wildner.Nm taskqueue_start_threads ,
42*cb24fcd4SSascha Wildner.Nm taskqueue_unblock ,
43a247c996SSascha Wildner.Nm TASK_INIT ,
44a247c996SSascha Wildner.Nm TASKQUEUE_DECLARE ,
45a247c996SSascha Wildner.Nm TASKQUEUE_DEFINE
46a247c996SSascha Wildner.Nd asynchronous task execution
47a247c996SSascha Wildner.Sh SYNOPSIS
48a247c996SSascha Wildner.In sys/param.h
49a247c996SSascha Wildner.In sys/kernel.h
50a247c996SSascha Wildner.In sys/malloc.h
51a247c996SSascha Wildner.In sys/queue.h
52a247c996SSascha Wildner.In sys/taskqueue.h
53a247c996SSascha Wildner.Bd -literal
54a247c996SSascha Wildnertypedef void (*task_fn_t)(void *context, int pending);
55a247c996SSascha Wildner
56a247c996SSascha Wildnertypedef void (*taskqueue_enqueue_fn)(void *context);
57a247c996SSascha Wildner
58a247c996SSascha Wildnerstruct task {
59a247c996SSascha Wildner	STAILQ_ENTRY(task)	ta_link;	/* link for queue */
60a247c996SSascha Wildner	int			ta_pending;	/* count times queued */
61a247c996SSascha Wildner	int			ta_priority;	/* priority of task in queue */
62a247c996SSascha Wildner	task_fn_t		ta_func;	/* task handler */
63a247c996SSascha Wildner	void			*ta_context;	/* argument for handler */
64a247c996SSascha Wildner};
65a247c996SSascha Wildner.Ed
66a247c996SSascha Wildner.Ft struct taskqueue *
67a247c996SSascha Wildner.Fn taskqueue_create "const char *name" "int mflags" "taskqueue_enqueue_fn enqueue" "void *context"
68a247c996SSascha Wildner.Ft void
69a247c996SSascha Wildner.Fn taskqueue_free "struct taskqueue *queue"
70a247c996SSascha Wildner.Ft struct taskqueue *
71a247c996SSascha Wildner.Fn taskqueue_find "const char *name"
72a247c996SSascha Wildner.Ft int
73a247c996SSascha Wildner.Fn taskqueue_enqueue "struct taskqueue *queue" "struct task *task"
74a247c996SSascha Wildner.Ft void
75a247c996SSascha Wildner.Fn taskqueue_run "struct taskqueue *queue"
76a0d61755SAlex Hornung.Ft void
77a0d61755SAlex Hornung.Fn taskqueue_drain "struct taskqueue *queue" "struct task *task"
78a0d61755SAlex Hornung.Ft void
79a0d61755SAlex Hornung.Fn taskqueue_block "struct taskqueue *queue"
80a0d61755SAlex Hornung.Ft void
81a0d61755SAlex Hornung.Fn taskqueue_unblock "struct taskqueue *queue"
82a0d61755SAlex Hornung.Ft int
8314ae2e95SAlex Hornung.Fn taskqueue_start_threads "struct taskqueue **tqp" "int count" "int pri" "int ncpu" "const char *fmt" "..."
84a247c996SSascha Wildner.Fn TASK_INIT "struct task *task" "int priority" "task_fn_t *func" "void *context"
85a247c996SSascha Wildner.Fn TASKQUEUE_DECLARE "name"
86a247c996SSascha Wildner.Fn TASKQUEUE_DEFINE "name" "taskqueue_enqueue_fn enqueue" "void *context" "init"
87a247c996SSascha Wildner.Sh DESCRIPTION
88a247c996SSascha WildnerThese functions provide a simple interface for asynchronous execution
89a247c996SSascha Wildnerof code.
90a247c996SSascha Wildner.Pp
91a247c996SSascha WildnerThe function
92a247c996SSascha Wildner.Fn taskqueue_create
93a247c996SSascha Wildneris used to create new queues.
94a247c996SSascha WildnerThe arguments to
95a247c996SSascha Wildner.Fn taskqueue_create
96a247c996SSascha Wildnerinclude a name that should be unique,
97a247c996SSascha Wildnera set of
9887909ed3SSascha Wildner.Xr kmalloc 9
99a247c996SSascha Wildnerflags that specify whether the call to
100a247c996SSascha Wildner.Fn malloc
101a247c996SSascha Wildneris allowed to sleep,
102a247c996SSascha Wildnerand a function which is called from
103a247c996SSascha Wildner.Fn taskqueue_enqueue
104a247c996SSascha Wildnerwhen a task is added to the queue
105a247c996SSascha Wildner.\" XXX	The rest of the sentence gets lots in relation to the first part.
106a247c996SSascha Wildnerto allow the queue to arrange to be run later
107a247c996SSascha Wildner(for instance by scheduling a software interrupt or waking a kernel
108a247c996SSascha Wildnerthread).
109a247c996SSascha Wildner.Pp
110a247c996SSascha WildnerThe function
111a247c996SSascha Wildner.Fn taskqueue_free
112a247c996SSascha Wildnershould be used to remove the queue from the global list of queues
113a247c996SSascha Wildnerand free the memory used by the queue.
114a247c996SSascha WildnerAny tasks that are on the queue will be executed at this time.
115a247c996SSascha Wildner.Pp
116a247c996SSascha WildnerThe system maintains a list of all queues which can be searched using
117a247c996SSascha Wildner.Fn taskqueue_find .
118a247c996SSascha WildnerThe first queue whose name matches is returned, otherwise
119a247c996SSascha Wildner.Dv NULL .
120a247c996SSascha Wildner.Pp
121a247c996SSascha WildnerTo add a task to the list of tasks queued on a taskqueue, call
122a247c996SSascha Wildner.Fn taskqueue_enqueue
123a247c996SSascha Wildnerwith pointers to the queue and task.
124a247c996SSascha WildnerIf the task's
125a247c996SSascha Wildner.Fa ta_pending
126a247c996SSascha Wildnerfield is non-zero,
127a247c996SSascha Wildnerthen it is simply incremented to reflect the number of times the task
128a247c996SSascha Wildnerwas enqueued.
129a247c996SSascha WildnerOtherwise,
130a247c996SSascha Wildnerthe task is added to the list before the first task which has a lower
131a247c996SSascha Wildner.Fa ta_priority
132a247c996SSascha Wildnervalue or at the end of the list if no tasks have a lower priority.
133a247c996SSascha WildnerEnqueueing a task does not perform any memory allocation which makes
134a247c996SSascha Wildnerit suitable for calling from an interrupt handler.
135a247c996SSascha WildnerThis function will return
136a247c996SSascha Wildner.Er EPIPE
137a247c996SSascha Wildnerif the queue is being freed.
138a247c996SSascha Wildner.Pp
139a247c996SSascha WildnerTo execute all the tasks on a queue,
140a247c996SSascha Wildnercall
141a247c996SSascha Wildner.Fn taskqueue_run .
142a247c996SSascha WildnerWhen a task is executed,
143a247c996SSascha Wildnerfirst it is removed from the queue,
144a247c996SSascha Wildnerthe value of
145a247c996SSascha Wildner.Fa ta_pending
146a247c996SSascha Wildneris recorded and then the field is zeroed.
147a247c996SSascha WildnerThe function
148a247c996SSascha Wildner.Fa ta_func
149a247c996SSascha Wildnerfrom the task structure is called with the value of the field
150a247c996SSascha Wildner.Fa ta_context
151a247c996SSascha Wildneras its first argument
152a247c996SSascha Wildnerand the value of
153a247c996SSascha Wildner.Fa ta_pending
154a247c996SSascha Wildneras its second argument.
155a247c996SSascha Wildner.Pp
156a0d61755SAlex HornungThe
157a0d61755SAlex Hornung.Fn taskqueue_drain
158a0d61755SAlex Hornungfunction is used to wait for the task to finish.
159a0d61755SAlex HornungThere is no guarantee that the task will not be
160a0d61755SAlex Hornungenqueued after call to
161a0d61755SAlex Hornung.Fn taskqueue_drain .
162a0d61755SAlex Hornung.Pp
163a0d61755SAlex HornungThe
164a0d61755SAlex Hornung.Fn taskqueue_block
165*cb24fcd4SSascha Wildnerfunction is used to block a taskqueue.
166*cb24fcd4SSascha WildnerWhen a taskqueue is blocked, calls to
167*cb24fcd4SSascha Wildner.Fn taskqueue_enqueue
168*cb24fcd4SSascha Wildnerwill still enqueue tasks but
169*cb24fcd4SSascha Wildnerthey will not be run until the taskqueue is unblocked by calling
170a0d61755SAlex Hornung.Fn taskqueue_unblock .
171a0d61755SAlex Hornung.Pp
172a0d61755SAlex HornungThe
173a0d61755SAlex Hornung.Fn taskqueue_start_threads
174a0d61755SAlex Hornungfunction is used to create and start
175a0d61755SAlex Hornung.Fa count
176a0d61755SAlex Hornungdedicated threads for the taskqueue specified by
177a0d61755SAlex Hornung.Fa tqp .
178a0d61755SAlex HornungThese threads will be created with the priority specified by
179a0d61755SAlex Hornung.Fa pri
180a0d61755SAlex Hornungand the name given by
181a0d61755SAlex Hornung.Fa fmt
182a0d61755SAlex Hornungwith _N appended to it, where N is the number of the thread.
18314ae2e95SAlex HornungIf
18414ae2e95SAlex Hornung.Fa count
185*cb24fcd4SSascha Wildner\*(Gt 1 and
18614ae2e95SAlex Hornung.Fa ncpu
18714ae2e95SAlex Hornungis -1, each of the
18814ae2e95SAlex Hornung.Fa count
18914ae2e95SAlex Hornungthreads will be allocated to a different
19014ae2e95SAlex HornungCPU among all available CPUs in a round robin fashion.
191a0d61755SAlex HornungThe taskqueue specified by
192a0d61755SAlex Hornung.Fa tqp
193a0d61755SAlex Hornungmust be created previously by calling
194a0d61755SAlex Hornung.Fn taskqueue_create
195a0d61755SAlex Hornungwith the argument
196a0d61755SAlex Hornung.Fa enqueue
197a0d61755SAlex Hornungset to
198a0d61755SAlex Hornung.Fa taskqueue_thread_enqueue .
199a0d61755SAlex Hornung.Pp
200a247c996SSascha WildnerA convenience macro,
201a247c996SSascha Wildner.Fn TASK_INIT
202a247c996SSascha Wildneris provided to initialise a
203a247c996SSascha Wildner.Vt task
204a247c996SSascha Wildnerstructure.
205a247c996SSascha WildnerThe values of
206a247c996SSascha Wildner.Fa priority ,
207a247c996SSascha Wildner.Fa func ,
208a247c996SSascha Wildnerand
209a247c996SSascha Wildner.Fa context
210a247c996SSascha Wildnerare simply copied into the task structure fields and the
211a247c996SSascha Wildner.Fa ta_pending
212a247c996SSascha Wildnerfield is cleared.
213a247c996SSascha Wildner.Pp
214a247c996SSascha WildnerTwo macros,
215a247c996SSascha Wildner.Fn TASKQUEUE_DECLARE
216a247c996SSascha Wildnerand
217a247c996SSascha Wildner.Fn TASKQUEUE_DEFINE
218a247c996SSascha Wildnerare used to declare a reference to a global queue,
219a247c996SSascha Wildnerand to define the implementation of the queue.
220a247c996SSascha WildnerThe
221a247c996SSascha Wildner.Fn TASKQUEUE_DEFINE
222a247c996SSascha Wildnermacro arranges to call
223a247c996SSascha Wildner.Fn taskqueue_create
224a247c996SSascha Wildnerwith the values of its
225a247c996SSascha Wildner.Fa name ,
226a247c996SSascha Wildner.Fa enqueue
227a247c996SSascha Wildnerand
228a247c996SSascha Wildner.Fa context
229a247c996SSascha Wildnerarguments during system initialisation.
230a247c996SSascha WildnerAfter calling
231a247c996SSascha Wildner.Fn taskqueue_create ,
232a247c996SSascha Wildnerthe
233a247c996SSascha Wildner.Fa init
234a247c996SSascha Wildnerargument to the macro is executed as a C statement,
235a247c996SSascha Wildnerallowing any further initialisation to be performed
236a247c996SSascha Wildner(such as registering an interrupt handler etc.)
237a247c996SSascha Wildner.Pp
238a0d61755SAlex HornungThe system provides two global taskqueues,
239*cb24fcd4SSascha Wildner.Va taskqueue_swi
240*cb24fcd4SSascha Wildnerand
241a0d61755SAlex Hornung.Va taskqueue_swi_mp ,
242a0d61755SAlex Hornungwhich are run via a software interrupt mechanism.
243a0d61755SAlex HornungTo use these queues, call
244a247c996SSascha Wildner.Fn taskqueue_enqueue
245a247c996SSascha Wildnerwith the value of the global variable
246*cb24fcd4SSascha Wildner.Va taskqueue_swi
247*cb24fcd4SSascha Wildneror
248a0d61755SAlex Hornung.Va taskqueue_swi_mp .
249a247c996SSascha Wildner.Pp
250a0d61755SAlex HornungWhile
251a0d61755SAlex Hornung.Va taskqueue_swi
252a0d61755SAlex Hornungacquires the mplock for its tasks,
253a0d61755SAlex Hornung.Va taskqueue_swi_mp
254a0d61755SAlex Hornungis intended for mpsafe tasks and no mplock will be acquired for them.
255a0d61755SAlex HornungThese queues can be used,
256a247c996SSascha Wildnerfor instance, for implementing interrupt handlers which must perform a
257a247c996SSascha Wildnersignificant amount of processing in the handler.
258a247c996SSascha WildnerThe hardware interrupt handler would perform minimal processing of the
259a247c996SSascha Wildnerinterrupt and then enqueue a task to finish the work.
260a247c996SSascha WildnerThis reduces to a minimum
261a247c996SSascha Wildnerthe amount of time spent with interrupts disabled.
262a247c996SSascha Wildner.\".Sh SEE ALSO
263a247c996SSascha Wildner.\".Xr ithread 9 ,
264a247c996SSascha Wildner.\".Xr kthread 9 ,
265a247c996SSascha Wildner.\".Xr swi 9
266a247c996SSascha Wildner.Sh HISTORY
267a247c996SSascha WildnerThis interface first appeared in
268a247c996SSascha Wildner.Fx 5.0 .
269a247c996SSascha WildnerThere is a similar facility called tqueue in the Linux kernel.
270a247c996SSascha Wildner.Sh AUTHORS
271a247c996SSascha WildnerThis manual page was written by
272a247c996SSascha Wildner.An Doug Rabson .
273