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