xref: /freebsd/share/man/man9/taskqueue.9 (revision c3bd10b434e16d881a04dfb5c67c5a845aaff661)
182323455SDoug Rabson.\" -*- nroff -*-
282323455SDoug Rabson.\"
382323455SDoug Rabson.\" Copyright (c) 2000 Doug Rabson
482323455SDoug Rabson.\"
582323455SDoug Rabson.\" All rights reserved.
682323455SDoug Rabson.\"
782323455SDoug Rabson.\" This program is free software.
882323455SDoug Rabson.\"
982323455SDoug Rabson.\" Redistribution and use in source and binary forms, with or without
1082323455SDoug Rabson.\" modification, are permitted provided that the following conditions
1182323455SDoug Rabson.\" are met:
1282323455SDoug Rabson.\" 1. Redistributions of source code must retain the above copyright
1382323455SDoug Rabson.\"    notice, this list of conditions and the following disclaimer.
1482323455SDoug Rabson.\" 2. Redistributions in binary form must reproduce the above copyright
1582323455SDoug Rabson.\"    notice, this list of conditions and the following disclaimer in the
1682323455SDoug Rabson.\"    documentation and/or other materials provided with the distribution.
1782323455SDoug Rabson.\"
1882323455SDoug Rabson.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
1982323455SDoug Rabson.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2082323455SDoug Rabson.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2182323455SDoug Rabson.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
2282323455SDoug Rabson.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2382323455SDoug Rabson.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2482323455SDoug Rabson.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2582323455SDoug Rabson.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2682323455SDoug Rabson.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2782323455SDoug Rabson.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2882323455SDoug Rabson.\"
2982323455SDoug Rabson.\" $FreeBSD$
3082323455SDoug Rabson.\"
31*c3bd10b4SKonstantin Belousov.Dd April 26, 2011
3282323455SDoug Rabson.Dt TASKQUEUE 9
3382323455SDoug Rabson.Os
3482323455SDoug Rabson.Sh NAME
3582323455SDoug Rabson.Nm taskqueue
3682323455SDoug Rabson.Nd asynchronous task execution
3782323455SDoug Rabson.Sh SYNOPSIS
3832eef9aeSRuslan Ermilov.In sys/param.h
39f16b3c0dSChad David.In sys/kernel.h
40f16b3c0dSChad David.In sys/malloc.h
4132eef9aeSRuslan Ermilov.In sys/queue.h
4232eef9aeSRuslan Ermilov.In sys/taskqueue.h
4382323455SDoug Rabson.Bd -literal
44f674e945SBruce M Simpsontypedef void (*task_fn_t)(void *context, int pending);
4582323455SDoug Rabson
4682323455SDoug Rabsontypedef void (*taskqueue_enqueue_fn)(void *context);
4782323455SDoug Rabson
4882323455SDoug Rabsonstruct task {
4982323455SDoug Rabson	STAILQ_ENTRY(task)	ta_link;	/* link for queue */
50cf82599dSSam Leffler	u_short			ta_pending;	/* count times queued */
51cf82599dSSam Leffler	u_short			ta_priority;	/* priority of task in queue */
52f674e945SBruce M Simpson	task_fn_t		ta_func;	/* task handler */
5382323455SDoug Rabson	void			*ta_context;	/* argument for handler */
5482323455SDoug Rabson};
55*c3bd10b4SKonstantin Belousov
56*c3bd10b4SKonstantin Belousovstruct timeout_task;
5782323455SDoug Rabson.Ed
5882323455SDoug Rabson.Ft struct taskqueue *
598f668ffaSOleksandr Tymoshenko.Fn taskqueue_create "const char *name" "int mflags" "taskqueue_enqueue_fn enqueue" "void *context"
602eb30874SOleksandr Tymoshenko.Ft struct taskqueue *
612eb30874SOleksandr Tymoshenko.Fn taskqueue_create_fast "const char *name" "int mflags" "taskqueue_enqueue_fn enqueue" "void *context"
6282323455SDoug Rabson.Ft void
6382323455SDoug Rabson.Fn taskqueue_free "struct taskqueue *queue"
6482323455SDoug Rabson.Ft int
6582323455SDoug Rabson.Fn taskqueue_enqueue "struct taskqueue *queue" "struct task *task"
6624b4e9d1SScott Long.Ft int
6724b4e9d1SScott Long.Fn taskqueue_enqueue_fast "struct taskqueue *queue" "struct task *task"
68f46276a9SMatthew D Fleming.Ft int
69*c3bd10b4SKonstantin Belousov.Fn taskqueue_enqueue_timeout "struct taskqueue *queue" "struct timeout_task *timeout_task" "int ticks"
70*c3bd10b4SKonstantin Belousov.Ft int
71f46276a9SMatthew D Fleming.Fn taskqueue_cancel "struct taskqueue *queue" "struct task *task" "u_int *pendp"
72*c3bd10b4SKonstantin Belousov.Ft int
73*c3bd10b4SKonstantin Belousov.Fn taskqueue_cancel_timeout "struct taskqueue *queue" "struct timeout_task *timeout_task" "u_int *pendp"
7482323455SDoug Rabson.Ft void
75fff7ff71SGleb Smirnoff.Fn taskqueue_drain "struct taskqueue *queue" "struct task *task"
76*c3bd10b4SKonstantin Belousov.Ft void
77*c3bd10b4SKonstantin Belousov.Fn taskqueue_drain_timeout "struct taskqueue *queue" "struct timeout_task *timeout_task"
78159ef108SPawel Jakub Dawidek.Ft int
79159ef108SPawel Jakub Dawidek.Fn taskqueue_member "struct taskqueue *queue" "struct thread *td"
80a92f0ee8SMatthew D Fleming.Ft void
81bf73d4d2SMatthew D Fleming.Fn taskqueue_run "struct taskqueue *queue"
82*c3bd10b4SKonstantin Belousov.Fn TASK_INIT "struct task *task" "int priority" "task_fn_t func" "void *context"
8382323455SDoug Rabson.Fn TASKQUEUE_DECLARE "name"
84f16b3c0dSChad David.Fn TASKQUEUE_DEFINE "name" "taskqueue_enqueue_fn enqueue" "void *context" "init"
852eb30874SOleksandr Tymoshenko.Fn TASKQUEUE_FAST_DEFINE "name" "taskqueue_enqueue_fn enqueue" "void *context" "init"
86227559d1SJohn-Mark Gurney.Fn TASKQUEUE_DEFINE_THREAD "name"
872eb30874SOleksandr Tymoshenko.Fn TASKQUEUE_FAST_DEFINE_THREAD "name"
88*c3bd10b4SKonstantin Belousov.Fn TIMEOUT_TASK_INIT "struct taskqueue *queue" "struct timeout_task *timeout_task" "int priority" "task_fn_t func" "void *context"
8982323455SDoug Rabson.Sh DESCRIPTION
9082323455SDoug RabsonThese functions provide a simple interface for asynchronous execution
9182323455SDoug Rabsonof code.
9282323455SDoug Rabson.Pp
9382323455SDoug RabsonThe function
9482323455SDoug Rabson.Fn taskqueue_create
9582323455SDoug Rabsonis used to create new queues.
9682323455SDoug RabsonThe arguments to
9782323455SDoug Rabson.Fn taskqueue_create
98cf82599dSSam Lefflerinclude a name that should be unique,
9982323455SDoug Rabsona set of
10082323455SDoug Rabson.Xr malloc 9
101cf82599dSSam Lefflerflags that specify whether the call to
10282323455SDoug Rabson.Fn malloc
103cf82599dSSam Leffleris allowed to sleep,
104cf82599dSSam Lefflera function that is called from
10582323455SDoug Rabson.Fn taskqueue_enqueue
106cf82599dSSam Lefflerwhen a task is added to the queue,
107cf82599dSSam Lefflerand a pointer to the memory location where the identity of the
108cf82599dSSam Lefflerthread that services the queue is recorded.
10982323455SDoug Rabson.\" XXX	The rest of the sentence gets lots in relation to the first part.
110cf82599dSSam LefflerThe function called from
111cf82599dSSam Leffler.Fn taskqueue_enqueue
112cf82599dSSam Lefflermust arrange for the queue to be processed
11382323455SDoug Rabson(for instance by scheduling a software interrupt or waking a kernel
11482323455SDoug Rabsonthread).
115cf82599dSSam LefflerThe memory location where the thread identity is recorded is used
116cf82599dSSam Lefflerto signal the service thread(s) to terminate--when this value is set to
117cf82599dSSam Lefflerzero and the thread is signaled it will terminate.
1182eb30874SOleksandr TymoshenkoIf the queue is intended for use in fast interrupt handlers
1192eb30874SOleksandr Tymoshenko.Fn taskqueue_create_fast
1202eb30874SOleksandr Tymoshenkoshould be used in place of
1212eb30874SOleksandr Tymoshenko.Fn taskqueue_create .
12282323455SDoug Rabson.Pp
12382323455SDoug RabsonThe function
12482323455SDoug Rabson.Fn taskqueue_free
125e477e4feSPawel Jakub Dawidekshould be used to free the memory used by the queue.
126cf82599dSSam LefflerAny tasks that are on the queue will be executed at this time after
127cf82599dSSam Lefflerwhich the thread servicing the queue will be signaled that it should exit.
12882323455SDoug Rabson.Pp
12982323455SDoug RabsonTo add a task to the list of tasks queued on a taskqueue, call
13082323455SDoug Rabson.Fn taskqueue_enqueue
13182323455SDoug Rabsonwith pointers to the queue and task.
13282323455SDoug RabsonIf the task's
13382323455SDoug Rabson.Va ta_pending
13482323455SDoug Rabsonfield is non-zero,
13582323455SDoug Rabsonthen it is simply incremented to reflect the number of times the task
13682323455SDoug Rabsonwas enqueued.
13782323455SDoug RabsonOtherwise,
13882323455SDoug Rabsonthe task is added to the list before the first task which has a lower
13982323455SDoug Rabson.Va ta_priority
14082323455SDoug Rabsonvalue or at the end of the list if no tasks have a lower priority.
14182323455SDoug RabsonEnqueueing a task does not perform any memory allocation which makes
14282323455SDoug Rabsonit suitable for calling from an interrupt handler.
14382323455SDoug RabsonThis function will return
144b92a189eSRuslan Ermilov.Er EPIPE
14582323455SDoug Rabsonif the queue is being freed.
14682323455SDoug Rabson.Pp
14724b4e9d1SScott LongThe function
14824b4e9d1SScott Long.Fn taskqueue_enqueue_fast
14924b4e9d1SScott Longshould be used in place of
15024b4e9d1SScott Long.Fn taskqueue_enqueue
15124b4e9d1SScott Longwhen the enqueuing must happen from a fast interrupt handler.
15224b4e9d1SScott LongThis method uses spin locks to avoid the possibility of sleeping in the fast
15324b4e9d1SScott Longinterrupt context.
15424b4e9d1SScott Long.Pp
15582323455SDoug RabsonWhen a task is executed,
15682323455SDoug Rabsonfirst it is removed from the queue,
15782323455SDoug Rabsonthe value of
15882323455SDoug Rabson.Va ta_pending
15982323455SDoug Rabsonis recorded and then the field is zeroed.
16082323455SDoug RabsonThe function
16182323455SDoug Rabson.Va ta_func
16282323455SDoug Rabsonfrom the task structure is called with the value of the field
16382323455SDoug Rabson.Va ta_context
16482323455SDoug Rabsonas its first argument
16582323455SDoug Rabsonand the value of
16682323455SDoug Rabson.Va ta_pending
16782323455SDoug Rabsonas its second argument.
168f616cf33SJohn-Mark GurneyAfter the function
169f616cf33SJohn-Mark Gurney.Va ta_func
170f616cf33SJohn-Mark Gurneyreturns,
171f616cf33SJohn-Mark Gurney.Xr wakeup 9
172f616cf33SJohn-Mark Gurneyis called on the task pointer passed to
173f616cf33SJohn-Mark Gurney.Fn taskqueue_enqueue .
17482323455SDoug Rabson.Pp
175fff7ff71SGleb SmirnoffThe
176*c3bd10b4SKonstantin Belousov.Fn taskqueue_enqueue_timeout
177*c3bd10b4SKonstantin Belousovis used to schedule the enqueue after the specified amount of
178*c3bd10b4SKonstantin Belousov.Va ticks .
179*c3bd10b4SKonstantin BelousovOnly non-fast task queues can be used for
180*c3bd10b4SKonstantin Belousov.Va timeout_task
181*c3bd10b4SKonstantin Belousovscheduling.
182*c3bd10b4SKonstantin Belousov.Pp
183*c3bd10b4SKonstantin BelousovThe
184f46276a9SMatthew D Fleming.Fn taskqueue_cancel
185f46276a9SMatthew D Flemingfunction is used to cancel a task.
186f46276a9SMatthew D FlemingThe
187f46276a9SMatthew D Fleming.Va ta_pending
188f46276a9SMatthew D Flemingcount is cleared, and the old value returned in the reference
189f46276a9SMatthew D Flemingparameter
190f46276a9SMatthew D Fleming.Fa pendp ,
191f46276a9SMatthew D Flemingif it is non- Dv NULL .
192f46276a9SMatthew D FlemingIf the task is currently running,
193f46276a9SMatthew D Fleming.Dv EBUSY
194f46276a9SMatthew D Flemingis returned, otherwise 0.
195f46276a9SMatthew D FlemingTo implement a blocking
196f46276a9SMatthew D Fleming.Fn taskqueue_cancel
197f46276a9SMatthew D Flemingthat waits for a running task to finish, it could look like:
198f46276a9SMatthew D Fleming.Bd -literal -offset indent
199f46276a9SMatthew D Flemingwhile (taskqueue_cancel(tq, task, NULL) != 0)
200f46276a9SMatthew D Fleming	taskqueue_drain(tq, task);
201f46276a9SMatthew D Fleming.Ed
202f46276a9SMatthew D Fleming.Pp
203f46276a9SMatthew D FlemingNote that, as with
204f46276a9SMatthew D Fleming.Fn taskqueue_drain ,
205f46276a9SMatthew D Flemingthe caller is responsible for ensuring that the task is not re-enqueued
206f46276a9SMatthew D Flemingafter being canceled.
207f46276a9SMatthew D Fleming.Pp
208*c3bd10b4SKonstantin BelousovSimilarly, the
209*c3bd10b4SKonstantin Belousov.Fn taskqueue_cancel_timeout
210*c3bd10b4SKonstantin Belousovfunction is used to cancel the scheduled task execution.
211*c3bd10b4SKonstantin Belousov.Pp
212f46276a9SMatthew D FlemingThe
213fff7ff71SGleb Smirnoff.Fn taskqueue_drain
214*c3bd10b4SKonstantin Belousovfunction is used to wait for the task to finish, and
215*c3bd10b4SKonstantin Belousovthe
216*c3bd10b4SKonstantin Belousov.Fn taskqueue_drain_timeout
217*c3bd10b4SKonstantin Belousovfunction is used to wait for the scheduled task to finish.
218fff7ff71SGleb SmirnoffThere is no guarantee that the task will not be
219fff7ff71SGleb Smirnoffenqueued after call to
220fff7ff71SGleb Smirnoff.Fn taskqueue_drain .
221fff7ff71SGleb Smirnoff.Pp
222159ef108SPawel Jakub DawidekThe
223159ef108SPawel Jakub Dawidek.Fn taskqueue_member
224159ef108SPawel Jakub Dawidekfunction returns
225159ef108SPawel Jakub Dawidek.No 1
2269c1a8ce4SPawel Jakub Dawidekif the given thread
227159ef108SPawel Jakub Dawidek.Fa td
2289ba47352SJoel Dahlis part of the given taskqueue
229159ef108SPawel Jakub Dawidek.Fa queue
230159ef108SPawel Jakub Dawidekand
231159ef108SPawel Jakub Dawidek.No 0
232159ef108SPawel Jakub Dawidekotherwise.
233159ef108SPawel Jakub Dawidek.Pp
234a92f0ee8SMatthew D FlemingThe
235a92f0ee8SMatthew D Fleming.Fn taskqueue_run
236a92f0ee8SMatthew D Flemingfunction will run all pending tasks in the specified
237a92f0ee8SMatthew D Fleming.Fa queue .
238a92f0ee8SMatthew D FlemingNormally this function is only used internally.
239a92f0ee8SMatthew D Fleming.Pp
24082323455SDoug RabsonA convenience macro,
24182323455SDoug Rabson.Fn TASK_INIT "task" "priority" "func" "context"
24282323455SDoug Rabsonis provided to initialise a
24382323455SDoug Rabson.Va task
24482323455SDoug Rabsonstructure.
245*c3bd10b4SKonstantin BelousovA macro
246*c3bd10b4SKonstantin Belousov.Fn TIMEOUT_TASK_INIT "queue" "timeout_task" "priority" "func" "context"
247*c3bd10b4SKonstantin Belousovinitializes the timeout_task structure.
24882323455SDoug RabsonThe values of
24982323455SDoug Rabson.Va priority ,
25082323455SDoug Rabson.Va func ,
25182323455SDoug Rabsonand
25282323455SDoug Rabson.Va context
25382323455SDoug Rabsonare simply copied into the task structure fields and the
25482323455SDoug Rabson.Va ta_pending
25582323455SDoug Rabsonfield is cleared.
25682323455SDoug Rabson.Pp
2572eb30874SOleksandr TymoshenkoFive macros
258227559d1SJohn-Mark Gurney.Fn TASKQUEUE_DECLARE "name" ,
259227559d1SJohn-Mark Gurney.Fn TASKQUEUE_DEFINE "name" "enqueue" "context" "init" ,
2602eb30874SOleksandr Tymoshenko.Fn TASKQUEUE_FAST_DEFINE "name" "enqueue" "context" "init" ,
26182323455SDoug Rabsonand
262227559d1SJohn-Mark Gurney.Fn TASKQUEUE_DEFINE_THREAD "name"
2632eb30874SOleksandr Tymoshenko.Fn TASKQUEUE_FAST_DEFINE_THREAD "name"
264227559d1SJohn-Mark Gurneyare used to declare a reference to a global queue, to define the
265c0854fb7SRuslan Ermilovimplementation of the queue, and declare a queue that uses its own thread.
26682323455SDoug RabsonThe
26782323455SDoug Rabson.Fn TASKQUEUE_DEFINE
26882323455SDoug Rabsonmacro arranges to call
26982323455SDoug Rabson.Fn taskqueue_create
27082323455SDoug Rabsonwith the values of its
27182323455SDoug Rabson.Va name ,
27282323455SDoug Rabson.Va enqueue
27382323455SDoug Rabsonand
27482323455SDoug Rabson.Va context
27582323455SDoug Rabsonarguments during system initialisation.
27682323455SDoug RabsonAfter calling
27782323455SDoug Rabson.Fn taskqueue_create ,
27882323455SDoug Rabsonthe
27982323455SDoug Rabson.Va init
28082323455SDoug Rabsonargument to the macro is executed as a C statement,
28182323455SDoug Rabsonallowing any further initialisation to be performed
28282323455SDoug Rabson(such as registering an interrupt handler etc.)
28382323455SDoug Rabson.Pp
284227559d1SJohn-Mark GurneyThe
285227559d1SJohn-Mark Gurney.Fn TASKQUEUE_DEFINE_THREAD
286c0854fb7SRuslan Ermilovmacro defines a new taskqueue with its own kernel thread to serve tasks.
287c0854fb7SRuslan ErmilovThe variable
288227559d1SJohn-Mark Gurney.Vt struct taskqueue *taskqueue_name
289227559d1SJohn-Mark Gurneyis used to enqueue tasks onto the queue.
2902eb30874SOleksandr Tymoshenko.Pp
2912eb30874SOleksandr Tymoshenko.Fn TASKQUEUE_FAST_DEFINE
2922eb30874SOleksandr Tymoshenkoand
2932eb30874SOleksandr Tymoshenko.Fn TASKQUEUE_FAST_DEFINE_THREAD
2942eb30874SOleksandr Tymoshenkoact just like
2952eb30874SOleksandr Tymoshenko.Fn TASKQUEUE_DEFINE
2962eb30874SOleksandr Tymoshenkoand
2972eb30874SOleksandr Tymoshenko.Fn TASKQUEUE_DEFINE_THREAD
2982eb30874SOleksandr Tymoshenkorespectively but taskqueue is created with
2992eb30874SOleksandr Tymoshenko.Fn taskqueue_create_fast .
3004c49b002SJoseph Koshy.Ss Predefined Task Queues
3014c49b002SJoseph KoshyThe system provides four global taskqueues,
3024c49b002SJoseph Koshy.Va taskqueue_fast ,
30382323455SDoug Rabson.Va taskqueue_swi ,
304cb32189eSKenneth D. Merry.Va taskqueue_swi_giant ,
305cb32189eSKenneth D. Merryand
306cb32189eSKenneth D. Merry.Va taskqueue_thread .
3074c49b002SJoseph KoshyThe
3084c49b002SJoseph Koshy.Va taskqueue_fast
3094c49b002SJoseph Koshyqueue is for swi handlers dispatched from fast interrupt handlers,
3104c49b002SJoseph Koshywhere sleep mutexes cannot be used.
311cb32189eSKenneth D. MerryThe swi taskqueues are run via a software interrupt mechanism.
3124c49b002SJoseph KoshyThe
3134c49b002SJoseph Koshy.Va taskqueue_swi
3144c49b002SJoseph Koshyqueue runs without the protection of the
3154c49b002SJoseph Koshy.Va Giant
3164c49b002SJoseph Koshykernel lock, and the
3174c49b002SJoseph Koshy.Va taskqueue_swi_giant
3184c49b002SJoseph Koshyqueue runs with the protection of the
3194c49b002SJoseph Koshy.Va Giant
320cb32189eSKenneth D. Merrykernel lock.
3214c49b002SJoseph KoshyThe thread taskqueue
3224c49b002SJoseph Koshy.Va taskqueue_thread
3234c49b002SJoseph Koshyruns in a kernel thread context, and tasks run from this thread do
3244c49b002SJoseph Koshynot run under the
3254c49b002SJoseph Koshy.Va Giant
3264c49b002SJoseph Koshykernel lock.
3274c49b002SJoseph KoshyIf the caller wants to run under
3284c49b002SJoseph Koshy.Va Giant ,
3294c49b002SJoseph Koshyhe should explicitly acquire and release
3304c49b002SJoseph Koshy.Va Giant
3314c49b002SJoseph Koshyin his taskqueue handler routine.
332bf7f20c2SRuslan Ermilov.Pp
333cb32189eSKenneth D. MerryTo use these queues,
33482323455SDoug Rabsoncall
33582323455SDoug Rabson.Fn taskqueue_enqueue
336cb32189eSKenneth D. Merrywith the value of the global taskqueue variable for the queue you wish to
337c0854fb7SRuslan Ermilovuse
338c0854fb7SRuslan Ermilov.Va ( taskqueue_swi ,
339cb32189eSKenneth D. Merry.Va taskqueue_swi_giant ,
340cb32189eSKenneth D. Merryor
341c0854fb7SRuslan Ermilov.Va taskqueue_thread ) .
3424c49b002SJoseph KoshyUse
3434c49b002SJoseph Koshy.Fn taskqueue_enqueue_fast
3444c49b002SJoseph Koshyfor the global taskqueue variable
3454c49b002SJoseph Koshy.Va taskqueue_fast .
34682323455SDoug Rabson.Pp
347e0254f10SKenneth D. MerryThe software interrupt queues can be used,
34882323455SDoug Rabsonfor instance, for implementing interrupt handlers which must perform a
34982323455SDoug Rabsonsignificant amount of processing in the handler.
35082323455SDoug RabsonThe hardware interrupt handler would perform minimal processing of the
35182323455SDoug Rabsoninterrupt and then enqueue a task to finish the work.
35282323455SDoug RabsonThis reduces to a minimum
35382323455SDoug Rabsonthe amount of time spent with interrupts disabled.
354cb32189eSKenneth D. Merry.Pp
355cb32189eSKenneth D. MerryThe thread queue can be used, for instance, by interrupt level routines
356cb32189eSKenneth D. Merrythat need to call kernel functions that do things that can only be done
357cb32189eSKenneth D. Merryfrom a thread context.
358cb32189eSKenneth D. Merry(e.g., call malloc with the M_WAITOK flag.)
359cf82599dSSam Leffler.Pp
360cf82599dSSam LefflerNote that tasks queued on shared taskqueues such as
361cf82599dSSam Leffler.Va taskqueue_swi
362cf82599dSSam Lefflermay be delayed an indeterminate amount of time before execution.
363cf82599dSSam LefflerIf queueing delays cannot be tolerated then a private taskqueue should
364cf82599dSSam Lefflerbe created with a dedicated processing thread.
3653bbf58f9SJoseph Koshy.Sh SEE ALSO
3663bbf58f9SJoseph Koshy.Xr ithread 9 ,
3673bbf58f9SJoseph Koshy.Xr kthread 9 ,
3683bbf58f9SJoseph Koshy.Xr swi 9
36982323455SDoug Rabson.Sh HISTORY
37082323455SDoug RabsonThis interface first appeared in
37182323455SDoug Rabson.Fx 5.0 .
372*c3bd10b4SKonstantin BelousovThere is a similar facility called work_queue in the Linux kernel.
37382323455SDoug Rabson.Sh AUTHORS
374571dba6eSHiten PandyaThis manual page was written by
37582323455SDoug Rabson.An Doug Rabson .
376