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