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