xref: /freebsd/share/man/man9/taskqueue.9 (revision 3becbb252c733d3d09172a34d7d00d27f84d0e86)
1.\" -*- nroff -*-
2.\"
3.\" Copyright (c) 2000 Doug Rabson
4.\"
5.\" All rights reserved.
6.\"
7.\" This program is free software.
8.\"
9.\" Redistribution and use in source and binary forms, with or without
10.\" modification, are permitted provided that the following conditions
11.\" are met:
12.\" 1. Redistributions of source code must retain the above copyright
13.\"    notice, this list of conditions and the following disclaimer.
14.\" 2. Redistributions in binary form must reproduce the above copyright
15.\"    notice, this list of conditions and the following disclaimer in the
16.\"    documentation and/or other materials provided with the distribution.
17.\"
18.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
19.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
22.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28.\"
29.\" $FreeBSD$
30.\"
31.Dd May 12, 2000
32.Dt TASKQUEUE 9
33.Os
34.Sh NAME
35.Nm taskqueue
36.Nd asynchronous task execution
37.Sh SYNOPSIS
38.In sys/param.h
39.In sys/queue.h
40.In sys/taskqueue.h
41.Bd -literal
42
43typedef void (*task_fn)(void *context, int pending);
44
45typedef void (*taskqueue_enqueue_fn)(void *context);
46
47struct task {
48	STAILQ_ENTRY(task)	ta_link;	/* link for queue */
49	int			ta_pending;	/* count times queued */
50	int			ta_priority;	/* priority of task in queue */
51	task_fn			ta_func;	/* task handler */
52	void			*ta_context;	/* argument for handler */
53};
54
55.Ed
56.Ft struct taskqueue *
57.Fn taskqueue_create "const char *name" "int mflags" "taskqueue_enqueue_fn enqueue" "void *context"
58.Ft void
59.Fn taskqueue_free "struct taskqueue *queue"
60.Ft struct taskqueue *
61.Fn taskqueue_find "const char *name"
62.Ft int
63.Fn taskqueue_enqueue "struct taskqueue *queue" "struct task *task"
64.Ft void
65.Fn taskqueue_run "struct taskqueue *queue"
66.Fn TASK_INIT "task" "priority" "func" "context"
67.Fn TASKQUEUE_DECLARE "name"
68.Fn TASKQUEUE_DEFINE "name" "enqueue" "context" "init"
69.Sh DESCRIPTION
70These functions provide a simple interface for asynchronous execution
71of code.
72.Pp
73The function
74.Fn taskqueue_create
75is used to create new queues.
76The arguments to
77.Fn taskqueue_create
78include a name which should be unique,
79a set of
80.Xr malloc 9
81flags which specify whether the call to
82.Fn malloc
83is allowed to sleep
84and a function which is called from
85.Fn taskqueue_enqueue
86when a task is added to the queue
87.\" XXX	The rest of the sentence gets lots in relation to the first part.
88to allow the queue to arrange to be run later
89(for instance by scheduling a software interrupt or waking a kernel
90thread).
91.Pp
92The function
93.Fn taskqueue_free
94should be used to remove the queue from the global list of queues
95and free the memory used by the queue.
96Any tasks which are on the queue will be executed at this time.
97.Pp
98The system maintains a list of all queues which can be searched using
99.Fn taskqueue_find .
100The first queue whose name matches is returned, otherwise
101.Dv NULL .
102.Pp
103To add a task to the list of tasks queued on a taskqueue, call
104.Fn taskqueue_enqueue
105with pointers to the queue and task.
106If the task's
107.Va ta_pending
108field is non-zero,
109then it is simply incremented to reflect the number of times the task
110was enqueued.
111Otherwise,
112the task is added to the list before the first task which has a lower
113.Va ta_priority
114value or at the end of the list if no tasks have a lower priority.
115Enqueueing a task does not perform any memory allocation which makes
116it suitable for calling from an interrupt handler.
117This function will return
118.Er EPIPE
119if the queue is being freed.
120.Pp
121To execute all the tasks on a queue,
122call
123.Fn taskqueue_run .
124When a task is executed,
125first it is removed from the queue,
126the value of
127.Va ta_pending
128is recorded and then the field is zeroed.
129The function
130.Va ta_func
131from the task structure is called with the value of the field
132.Va ta_context
133as its first argument
134and the value of
135.Va ta_pending
136as its second argument.
137.Pp
138A convenience macro,
139.Fn TASK_INIT "task" "priority" "func" "context"
140is provided to initialise a
141.Va task
142structure.
143The values of
144.Va priority ,
145.Va func ,
146and
147.Va context
148are simply copied into the task structure fields and the
149.Va ta_pending
150field is cleared.
151.Pp
152Two macros
153.Fn TASKQUEUE_DECLARE "name"
154and
155.Fn TASKQUEUE_DEFINE "name" "enqueue" "context" "init"
156are used to declare a reference to a global queue
157and to define the implementation of the queue.
158The
159.Fn TASKQUEUE_DEFINE
160macro arranges to call
161.Fn taskqueue_create
162with the values of its
163.Va name ,
164.Va enqueue
165and
166.Va context
167arguments during system initialisation.
168After calling
169.Fn taskqueue_create ,
170the
171.Va init
172argument to the macro is executed as a C statement,
173allowing any further initialisation to be performed
174(such as registering an interrupt handler etc.)
175.Pp
176The system provides a global taskqueue,
177.Va taskqueue_swi ,
178which is run via a software interrupt mechanism.
179To use this queue,
180call
181.Fn taskqueue_enqueue
182with the value of the global variable
183.Va taskqueue_swi .
184The queue will be run at
185.\" XXX	This should be a cross-reference (Xr), but there is no MANLINKS
186.\"	entry for splsofttq.9 yet.
187.Fn splsofttq .
188.Pp
189This queue can be used,
190for instance, for implementing interrupt handlers which must perform a
191significant amount of processing in the handler.
192The hardware interrupt handler would perform minimal processing of the
193interrupt and then enqueue a task to finish the work.
194This reduces to a minimum
195the amount of time spent with interrupts disabled.
196.Sh HISTORY
197This interface first appeared in
198.Fx 5.0 .
199There is a similar facility called tqueue in the Linux kernel.
200.Sh AUTHORS
201This man page was written by
202.An Doug Rabson .
203