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