xref: /freebsd/share/man/man9/taskqueue.9 (revision ec5d37f4f5deb7ec123d9c9cdbc0b37a6d66688b)
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*ec5d37f4SBenjamin Kaduk.Dd May 24, 2014
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};
55c3bd10b4SKonstantin Belousov
56fdbc7174SWill Andrewsenum taskqueue_callback_type {
57fdbc7174SWill Andrews	TASKQUEUE_CALLBACK_TYPE_INIT,
58fdbc7174SWill Andrews	TASKQUEUE_CALLBACK_TYPE_SHUTDOWN,
59fdbc7174SWill Andrews};
60fdbc7174SWill Andrews
61fdbc7174SWill Andrewstypedef void (*taskqueue_callback_fn)(void *context);
62fdbc7174SWill Andrews
63c3bd10b4SKonstantin Belousovstruct timeout_task;
6482323455SDoug Rabson.Ed
6582323455SDoug Rabson.Ft struct taskqueue *
668f668ffaSOleksandr Tymoshenko.Fn taskqueue_create "const char *name" "int mflags" "taskqueue_enqueue_fn enqueue" "void *context"
672eb30874SOleksandr Tymoshenko.Ft struct taskqueue *
682eb30874SOleksandr Tymoshenko.Fn taskqueue_create_fast "const char *name" "int mflags" "taskqueue_enqueue_fn enqueue" "void *context"
69fdbc7174SWill Andrews.Ft int
70fdbc7174SWill Andrews.Fn taskqueue_start_threads "struct taskqueue **tqp" "int count" "int pri" "const char *name" "..."
71*ec5d37f4SBenjamin Kaduk.Ft int
72*ec5d37f4SBenjamin Kaduk.Fo taskqueue_start_threads_pinned
73*ec5d37f4SBenjamin Kaduk.Fa "struct taskqueue **tqp" "int count" "int pri" "int cpu_id"
74*ec5d37f4SBenjamin Kaduk.Fa "const char *name" "..."
75*ec5d37f4SBenjamin Kaduk.Fc
76fdbc7174SWill Andrews.Ft void
77fdbc7174SWill Andrews.Fn taskqueue_set_callback "struct taskqueue *queue" "enum taskqueue_callback_type cb_type" "taskqueue_callback_fn callback" "void *context"
7882323455SDoug Rabson.Ft void
7982323455SDoug Rabson.Fn taskqueue_free "struct taskqueue *queue"
8082323455SDoug Rabson.Ft int
8182323455SDoug Rabson.Fn taskqueue_enqueue "struct taskqueue *queue" "struct task *task"
8224b4e9d1SScott Long.Ft int
8324b4e9d1SScott Long.Fn taskqueue_enqueue_fast "struct taskqueue *queue" "struct task *task"
84f46276a9SMatthew D Fleming.Ft int
85c3bd10b4SKonstantin Belousov.Fn taskqueue_enqueue_timeout "struct taskqueue *queue" "struct timeout_task *timeout_task" "int ticks"
86c3bd10b4SKonstantin Belousov.Ft int
87f46276a9SMatthew D Fleming.Fn taskqueue_cancel "struct taskqueue *queue" "struct task *task" "u_int *pendp"
88c3bd10b4SKonstantin Belousov.Ft int
89c3bd10b4SKonstantin Belousov.Fn taskqueue_cancel_timeout "struct taskqueue *queue" "struct timeout_task *timeout_task" "u_int *pendp"
9082323455SDoug Rabson.Ft void
91fff7ff71SGleb Smirnoff.Fn taskqueue_drain "struct taskqueue *queue" "struct task *task"
92c3bd10b4SKonstantin Belousov.Ft void
93c3bd10b4SKonstantin Belousov.Fn taskqueue_drain_timeout "struct taskqueue *queue" "struct timeout_task *timeout_task"
94cb03508fSAndriy Gapon.Ft void
95cb03508fSAndriy Gapon.Fn taskqueue_drain_all "struct taskqueue *queue"
96cb03508fSAndriy Gapon.Ft void
97cb03508fSAndriy Gapon.Fn taskqueue_block "struct taskqueue *queue"
98cb03508fSAndriy Gapon.Ft void
99cb03508fSAndriy Gapon.Fn taskqueue_unblock "struct taskqueue *queue"
100159ef108SPawel Jakub Dawidek.Ft int
101159ef108SPawel Jakub Dawidek.Fn taskqueue_member "struct taskqueue *queue" "struct thread *td"
102a92f0ee8SMatthew D Fleming.Ft void
103bf73d4d2SMatthew D Fleming.Fn taskqueue_run "struct taskqueue *queue"
104c3bd10b4SKonstantin Belousov.Fn TASK_INIT "struct task *task" "int priority" "task_fn_t func" "void *context"
105a7f5f794SJohn Baldwin.Fn TASK_INITIALIZER "int priority" "task_fn_t func" "void *context"
10682323455SDoug Rabson.Fn TASKQUEUE_DECLARE "name"
107f16b3c0dSChad David.Fn TASKQUEUE_DEFINE "name" "taskqueue_enqueue_fn enqueue" "void *context" "init"
1082eb30874SOleksandr Tymoshenko.Fn TASKQUEUE_FAST_DEFINE "name" "taskqueue_enqueue_fn enqueue" "void *context" "init"
109227559d1SJohn-Mark Gurney.Fn TASKQUEUE_DEFINE_THREAD "name"
1102eb30874SOleksandr Tymoshenko.Fn TASKQUEUE_FAST_DEFINE_THREAD "name"
111c3bd10b4SKonstantin Belousov.Fn TIMEOUT_TASK_INIT "struct taskqueue *queue" "struct timeout_task *timeout_task" "int priority" "task_fn_t func" "void *context"
11282323455SDoug Rabson.Sh DESCRIPTION
11382323455SDoug RabsonThese functions provide a simple interface for asynchronous execution
11482323455SDoug Rabsonof code.
11582323455SDoug Rabson.Pp
11682323455SDoug RabsonThe function
11782323455SDoug Rabson.Fn taskqueue_create
11882323455SDoug Rabsonis used to create new queues.
11982323455SDoug RabsonThe arguments to
12082323455SDoug Rabson.Fn taskqueue_create
121cf82599dSSam Lefflerinclude a name that should be unique,
12282323455SDoug Rabsona set of
12382323455SDoug Rabson.Xr malloc 9
124cf82599dSSam Lefflerflags that specify whether the call to
12582323455SDoug Rabson.Fn malloc
126cf82599dSSam Leffleris allowed to sleep,
127cf82599dSSam Lefflera function that is called from
12882323455SDoug Rabson.Fn taskqueue_enqueue
129cf82599dSSam Lefflerwhen a task is added to the queue,
130cf82599dSSam Lefflerand a pointer to the memory location where the identity of the
131cf82599dSSam Lefflerthread that services the queue is recorded.
13282323455SDoug Rabson.\" XXX	The rest of the sentence gets lots in relation to the first part.
133cf82599dSSam LefflerThe function called from
134cf82599dSSam Leffler.Fn taskqueue_enqueue
135cf82599dSSam Lefflermust arrange for the queue to be processed
13682323455SDoug Rabson(for instance by scheduling a software interrupt or waking a kernel
13782323455SDoug Rabsonthread).
138cf82599dSSam LefflerThe memory location where the thread identity is recorded is used
139cf82599dSSam Lefflerto signal the service thread(s) to terminate--when this value is set to
140cf82599dSSam Lefflerzero and the thread is signaled it will terminate.
1412eb30874SOleksandr TymoshenkoIf the queue is intended for use in fast interrupt handlers
1422eb30874SOleksandr Tymoshenko.Fn taskqueue_create_fast
1432eb30874SOleksandr Tymoshenkoshould be used in place of
1442eb30874SOleksandr Tymoshenko.Fn taskqueue_create .
14582323455SDoug Rabson.Pp
14682323455SDoug RabsonThe function
14782323455SDoug Rabson.Fn taskqueue_free
148e477e4feSPawel Jakub Dawidekshould be used to free the memory used by the queue.
149cf82599dSSam LefflerAny tasks that are on the queue will be executed at this time after
150cf82599dSSam Lefflerwhich the thread servicing the queue will be signaled that it should exit.
15182323455SDoug Rabson.Pp
152fdbc7174SWill AndrewsOnce a taskqueue has been created, its threads should be started using
153*ec5d37f4SBenjamin Kaduk.Fn taskqueue_start_threads
154*ec5d37f4SBenjamin Kadukor
155*ec5d37f4SBenjamin Kaduk.Fn taskqueue_start_threads_pinned .
156*ec5d37f4SBenjamin Kaduk.Fn taskqueue_start_threads_pinned
157*ec5d37f4SBenjamin Kaduktakes a
158*ec5d37f4SBenjamin Kaduk.Va cpu_id
159*ec5d37f4SBenjamin Kadukargument which will cause the threads which are started for the taskqueue
160*ec5d37f4SBenjamin Kadukto be pinned to run on the given CPU.
161fdbc7174SWill AndrewsCallbacks may optionally be registered using
162fdbc7174SWill Andrews.Fn taskqueue_set_callback .
163fdbc7174SWill AndrewsCurrently, callbacks may be registered for the following purposes:
164fdbc7174SWill Andrews.Bl -tag -width TASKQUEUE_CALLBACK_TYPE_SHUTDOWN
165fdbc7174SWill Andrews.It Dv TASKQUEUE_CALLBACK_TYPE_INIT
166fdbc7174SWill AndrewsThis callback is called by every thread in the taskqueue, before it executes
167fdbc7174SWill Andrewsany tasks.
168fdbc7174SWill AndrewsThis callback must be set before the taskqueue's threads are started.
169fdbc7174SWill Andrews.It Dv TASKQUEUE_CALLBACK_TYPE_SHUTDOWN
170fdbc7174SWill AndrewsThis callback is called by every thread in the taskqueue, after it executes
171fdbc7174SWill Andrewsits last task.
172fdbc7174SWill AndrewsThis callback will always be called before the taskqueue structure is
173fdbc7174SWill Andrewsreclaimed.
174fdbc7174SWill Andrews.El
175fdbc7174SWill Andrews.Pp
17682323455SDoug RabsonTo add a task to the list of tasks queued on a taskqueue, call
17782323455SDoug Rabson.Fn taskqueue_enqueue
17882323455SDoug Rabsonwith pointers to the queue and task.
17982323455SDoug RabsonIf the task's
18082323455SDoug Rabson.Va ta_pending
18182323455SDoug Rabsonfield is non-zero,
18282323455SDoug Rabsonthen it is simply incremented to reflect the number of times the task
183d2849f27SAdrian Chaddwas enqueued, up to a cap of USHRT_MAX.
18482323455SDoug RabsonOtherwise,
18582323455SDoug Rabsonthe task is added to the list before the first task which has a lower
18682323455SDoug Rabson.Va ta_priority
18782323455SDoug Rabsonvalue or at the end of the list if no tasks have a lower priority.
18882323455SDoug RabsonEnqueueing a task does not perform any memory allocation which makes
18982323455SDoug Rabsonit suitable for calling from an interrupt handler.
19082323455SDoug RabsonThis function will return
191b92a189eSRuslan Ermilov.Er EPIPE
19282323455SDoug Rabsonif the queue is being freed.
19382323455SDoug Rabson.Pp
19424b4e9d1SScott LongThe function
19524b4e9d1SScott Long.Fn taskqueue_enqueue_fast
19624b4e9d1SScott Longshould be used in place of
19724b4e9d1SScott Long.Fn taskqueue_enqueue
19824b4e9d1SScott Longwhen the enqueuing must happen from a fast interrupt handler.
19924b4e9d1SScott LongThis method uses spin locks to avoid the possibility of sleeping in the fast
20024b4e9d1SScott Longinterrupt context.
20124b4e9d1SScott Long.Pp
20282323455SDoug RabsonWhen a task is executed,
20382323455SDoug Rabsonfirst it is removed from the queue,
20482323455SDoug Rabsonthe value of
20582323455SDoug Rabson.Va ta_pending
20682323455SDoug Rabsonis recorded and then the field is zeroed.
20782323455SDoug RabsonThe function
20882323455SDoug Rabson.Va ta_func
20982323455SDoug Rabsonfrom the task structure is called with the value of the field
21082323455SDoug Rabson.Va ta_context
21182323455SDoug Rabsonas its first argument
21282323455SDoug Rabsonand the value of
21382323455SDoug Rabson.Va ta_pending
21482323455SDoug Rabsonas its second argument.
215f616cf33SJohn-Mark GurneyAfter the function
216f616cf33SJohn-Mark Gurney.Va ta_func
217f616cf33SJohn-Mark Gurneyreturns,
218f616cf33SJohn-Mark Gurney.Xr wakeup 9
219f616cf33SJohn-Mark Gurneyis called on the task pointer passed to
220f616cf33SJohn-Mark Gurney.Fn taskqueue_enqueue .
22182323455SDoug Rabson.Pp
222fff7ff71SGleb SmirnoffThe
223c3bd10b4SKonstantin Belousov.Fn taskqueue_enqueue_timeout
224c3bd10b4SKonstantin Belousovis used to schedule the enqueue after the specified amount of
225c3bd10b4SKonstantin Belousov.Va ticks .
226c3bd10b4SKonstantin BelousovOnly non-fast task queues can be used for
227c3bd10b4SKonstantin Belousov.Va timeout_task
228c3bd10b4SKonstantin Belousovscheduling.
229471af3a8SKonstantin BelousovIf the
230471af3a8SKonstantin Belousov.Va ticks
231471af3a8SKonstantin Belousovargument is negative, the already scheduled enqueueing is not re-scheduled.
232c1e231bcSKonstantin BelousovOtherwise, the task is scheduled for enqueueing in the future,
233471af3a8SKonstantin Belousovafter the absolute value of
234471af3a8SKonstantin Belousov.Va ticks
235471af3a8SKonstantin Belousovis passed.
236c3bd10b4SKonstantin Belousov.Pp
237c3bd10b4SKonstantin BelousovThe
238f46276a9SMatthew D Fleming.Fn taskqueue_cancel
239f46276a9SMatthew D Flemingfunction is used to cancel a task.
240f46276a9SMatthew D FlemingThe
241f46276a9SMatthew D Fleming.Va ta_pending
242f46276a9SMatthew D Flemingcount is cleared, and the old value returned in the reference
243f46276a9SMatthew D Flemingparameter
244f46276a9SMatthew D Fleming.Fa pendp ,
24573bbeaa5SGlen Barberif it is
24673bbeaa5SGlen Barber.Pf non- Dv NULL .
247f46276a9SMatthew D FlemingIf the task is currently running,
248f46276a9SMatthew D Fleming.Dv EBUSY
249f46276a9SMatthew D Flemingis returned, otherwise 0.
250f46276a9SMatthew D FlemingTo implement a blocking
251f46276a9SMatthew D Fleming.Fn taskqueue_cancel
252f46276a9SMatthew D Flemingthat waits for a running task to finish, it could look like:
253f46276a9SMatthew D Fleming.Bd -literal -offset indent
254f46276a9SMatthew D Flemingwhile (taskqueue_cancel(tq, task, NULL) != 0)
255f46276a9SMatthew D Fleming	taskqueue_drain(tq, task);
256f46276a9SMatthew D Fleming.Ed
257f46276a9SMatthew D Fleming.Pp
258f46276a9SMatthew D FlemingNote that, as with
259f46276a9SMatthew D Fleming.Fn taskqueue_drain ,
260f46276a9SMatthew D Flemingthe caller is responsible for ensuring that the task is not re-enqueued
261f46276a9SMatthew D Flemingafter being canceled.
262f46276a9SMatthew D Fleming.Pp
263c3bd10b4SKonstantin BelousovSimilarly, the
264c3bd10b4SKonstantin Belousov.Fn taskqueue_cancel_timeout
265c3bd10b4SKonstantin Belousovfunction is used to cancel the scheduled task execution.
266c3bd10b4SKonstantin Belousov.Pp
267f46276a9SMatthew D FlemingThe
268fff7ff71SGleb Smirnoff.Fn taskqueue_drain
269c3bd10b4SKonstantin Belousovfunction is used to wait for the task to finish, and
270c3bd10b4SKonstantin Belousovthe
271c3bd10b4SKonstantin Belousov.Fn taskqueue_drain_timeout
272c3bd10b4SKonstantin Belousovfunction is used to wait for the scheduled task to finish.
273fff7ff71SGleb SmirnoffThere is no guarantee that the task will not be
274fff7ff71SGleb Smirnoffenqueued after call to
275fff7ff71SGleb Smirnoff.Fn taskqueue_drain .
276cb03508fSAndriy GaponIf the caller wants to put the task into a known state,
277cb03508fSAndriy Gaponthen before calling
278cb03508fSAndriy Gapon.Fn taskqueue_drain
279cb03508fSAndriy Gaponthe caller should use out-of-band means to ensure that the task
280cb03508fSAndriy Gaponwould not be enqueued.
281cb03508fSAndriy GaponFor example, if the task is enqueued by an interrupt filter, then
282cb03508fSAndriy Gaponthe interrupt could be disabled.
283cb03508fSAndriy Gapon.Pp
284cb03508fSAndriy GaponThe
285cb03508fSAndriy Gapon.Fn taskqueue_drain_all
286cb03508fSAndriy Gaponfunction is used to wait for all pending and running tasks that
287cb03508fSAndriy Gaponare enqueued on the taskqueue to finish.
288cb03508fSAndriy GaponThe caller must arrange that the tasks are not re-enqueued.
289cb03508fSAndriy GaponNote that
290cb03508fSAndriy Gapon.Fn taskqueue_drain_all
291cb03508fSAndriy Gaponcurrently does not handle tasks with delayed enqueueing.
292cb03508fSAndriy Gapon.Pp
293cb03508fSAndriy GaponThe
294cb03508fSAndriy Gapon.Fn taskqueue_block
295cb03508fSAndriy Gaponfunction blocks the taskqueue.
296cb03508fSAndriy GaponIt prevents any enqueued but not running tasks from being executed.
297cb03508fSAndriy GaponFuture calls to
298cb03508fSAndriy Gapon.Fn taskqueue_enqueue
299cb03508fSAndriy Gaponwill enqueue tasks, but the tasks will not be run until
300cb03508fSAndriy Gapon.Fn taskqueue_unblock
301cb03508fSAndriy Gaponis called.
302cb03508fSAndriy GaponPlease note that
303cb03508fSAndriy Gapon.Fn taskqueue_block
304cb03508fSAndriy Gapondoes not wait for any currently running tasks to finish.
305cb03508fSAndriy GaponThus, the
306cb03508fSAndriy Gapon.Fn taskqueue_block
307cb03508fSAndriy Gapondoes not provide a guarantee that
308cb03508fSAndriy Gapon.Fn taskqueue_run
309cb03508fSAndriy Gaponis not running after
310cb03508fSAndriy Gapon.Fn taskqueue_block
311cb03508fSAndriy Gaponreturns, but it does provide a guarantee that
312cb03508fSAndriy Gapon.Fn taskqueue_run
313cb03508fSAndriy Gaponwill not be called again
314cb03508fSAndriy Gaponuntil
315cb03508fSAndriy Gapon.Fn taskqueue_unblock
316cb03508fSAndriy Gaponis called.
317cb03508fSAndriy GaponIf the caller requires a guarantee that
318cb03508fSAndriy Gapon.Fn taskqueue_run
319cb03508fSAndriy Gaponis not running, then this must be arranged by the caller.
320cb03508fSAndriy GaponNote that if
321cb03508fSAndriy Gapon.Fn taskqueue_drain
322cb03508fSAndriy Gaponis called on a task that is enqueued on a taskqueue that is blocked by
323cb03508fSAndriy Gapon.Fn taskqueue_block ,
324cb03508fSAndriy Gaponthen
325cb03508fSAndriy Gapon.Fn taskqueue_drain
326cb03508fSAndriy Gaponcan not return until the taskqueue is unblocked.
327cb03508fSAndriy GaponThis can result in a deadlock if the thread blocked in
328cb03508fSAndriy Gapon.Fn taskqueue_drain
329cb03508fSAndriy Gaponis the thread that is supposed to call
330cb03508fSAndriy Gapon.Fn taskqueue_unblock .
331cb03508fSAndriy GaponThus, use of
332cb03508fSAndriy Gapon.Fn taskqueue_drain
333cb03508fSAndriy Gaponafter
334cb03508fSAndriy Gapon.Fn taskqueue_block
335cb03508fSAndriy Gaponis discouraged, because the state of the task can not be known in advance.
336cb03508fSAndriy GaponThe same caveat applies to
337cb03508fSAndriy Gapon.Fn taskqueue_drain_all .
338cb03508fSAndriy Gapon.Pp
339cb03508fSAndriy GaponThe
340cb03508fSAndriy Gapon.Fn taskqueue_unblock
341cb03508fSAndriy Gaponfunction unblocks the previously blocked taskqueue.
342cb03508fSAndriy GaponAll enqueued tasks can be run after this call.
343fff7ff71SGleb Smirnoff.Pp
344159ef108SPawel Jakub DawidekThe
345159ef108SPawel Jakub Dawidek.Fn taskqueue_member
346159ef108SPawel Jakub Dawidekfunction returns
347159ef108SPawel Jakub Dawidek.No 1
3489c1a8ce4SPawel Jakub Dawidekif the given thread
349159ef108SPawel Jakub Dawidek.Fa td
3509ba47352SJoel Dahlis part of the given taskqueue
351159ef108SPawel Jakub Dawidek.Fa queue
352159ef108SPawel Jakub Dawidekand
353159ef108SPawel Jakub Dawidek.No 0
354159ef108SPawel Jakub Dawidekotherwise.
355159ef108SPawel Jakub Dawidek.Pp
356a92f0ee8SMatthew D FlemingThe
357a92f0ee8SMatthew D Fleming.Fn taskqueue_run
358a92f0ee8SMatthew D Flemingfunction will run all pending tasks in the specified
359a92f0ee8SMatthew D Fleming.Fa queue .
360a92f0ee8SMatthew D FlemingNormally this function is only used internally.
361a92f0ee8SMatthew D Fleming.Pp
36282323455SDoug RabsonA convenience macro,
36382323455SDoug Rabson.Fn TASK_INIT "task" "priority" "func" "context"
36482323455SDoug Rabsonis provided to initialise a
36582323455SDoug Rabson.Va task
36682323455SDoug Rabsonstructure.
367a7f5f794SJohn BaldwinThe
368a7f5f794SJohn Baldwin.Fn TASK_INITIALIZER
369a7f5f794SJohn Baldwinmacro generates an initializer for a task structure.
370c3bd10b4SKonstantin BelousovA macro
371c3bd10b4SKonstantin Belousov.Fn TIMEOUT_TASK_INIT "queue" "timeout_task" "priority" "func" "context"
372a7f5f794SJohn Baldwininitializes the
373a7f5f794SJohn Baldwin.Va timeout_task
374a7f5f794SJohn Baldwinstructure.
37582323455SDoug RabsonThe values of
37682323455SDoug Rabson.Va priority ,
37782323455SDoug Rabson.Va func ,
37882323455SDoug Rabsonand
37982323455SDoug Rabson.Va context
38082323455SDoug Rabsonare simply copied into the task structure fields and the
38182323455SDoug Rabson.Va ta_pending
38282323455SDoug Rabsonfield is cleared.
38382323455SDoug Rabson.Pp
3842eb30874SOleksandr TymoshenkoFive macros
385227559d1SJohn-Mark Gurney.Fn TASKQUEUE_DECLARE "name" ,
386227559d1SJohn-Mark Gurney.Fn TASKQUEUE_DEFINE "name" "enqueue" "context" "init" ,
3872eb30874SOleksandr Tymoshenko.Fn TASKQUEUE_FAST_DEFINE "name" "enqueue" "context" "init" ,
38882323455SDoug Rabsonand
389227559d1SJohn-Mark Gurney.Fn TASKQUEUE_DEFINE_THREAD "name"
3902eb30874SOleksandr Tymoshenko.Fn TASKQUEUE_FAST_DEFINE_THREAD "name"
391227559d1SJohn-Mark Gurneyare used to declare a reference to a global queue, to define the
392c0854fb7SRuslan Ermilovimplementation of the queue, and declare a queue that uses its own thread.
39382323455SDoug RabsonThe
39482323455SDoug Rabson.Fn TASKQUEUE_DEFINE
39582323455SDoug Rabsonmacro arranges to call
39682323455SDoug Rabson.Fn taskqueue_create
39782323455SDoug Rabsonwith the values of its
39882323455SDoug Rabson.Va name ,
39982323455SDoug Rabson.Va enqueue
40082323455SDoug Rabsonand
40182323455SDoug Rabson.Va context
40282323455SDoug Rabsonarguments during system initialisation.
40382323455SDoug RabsonAfter calling
40482323455SDoug Rabson.Fn taskqueue_create ,
40582323455SDoug Rabsonthe
40682323455SDoug Rabson.Va init
40782323455SDoug Rabsonargument to the macro is executed as a C statement,
40882323455SDoug Rabsonallowing any further initialisation to be performed
40982323455SDoug Rabson(such as registering an interrupt handler etc.)
41082323455SDoug Rabson.Pp
411227559d1SJohn-Mark GurneyThe
412227559d1SJohn-Mark Gurney.Fn TASKQUEUE_DEFINE_THREAD
413c0854fb7SRuslan Ermilovmacro defines a new taskqueue with its own kernel thread to serve tasks.
414c0854fb7SRuslan ErmilovThe variable
415227559d1SJohn-Mark Gurney.Vt struct taskqueue *taskqueue_name
416227559d1SJohn-Mark Gurneyis used to enqueue tasks onto the queue.
4172eb30874SOleksandr Tymoshenko.Pp
4182eb30874SOleksandr Tymoshenko.Fn TASKQUEUE_FAST_DEFINE
4192eb30874SOleksandr Tymoshenkoand
4202eb30874SOleksandr Tymoshenko.Fn TASKQUEUE_FAST_DEFINE_THREAD
4212eb30874SOleksandr Tymoshenkoact just like
4222eb30874SOleksandr Tymoshenko.Fn TASKQUEUE_DEFINE
4232eb30874SOleksandr Tymoshenkoand
4242eb30874SOleksandr Tymoshenko.Fn TASKQUEUE_DEFINE_THREAD
4252eb30874SOleksandr Tymoshenkorespectively but taskqueue is created with
4262eb30874SOleksandr Tymoshenko.Fn taskqueue_create_fast .
4274c49b002SJoseph Koshy.Ss Predefined Task Queues
4284c49b002SJoseph KoshyThe system provides four global taskqueues,
4294c49b002SJoseph Koshy.Va taskqueue_fast ,
43082323455SDoug Rabson.Va taskqueue_swi ,
431cb32189eSKenneth D. Merry.Va taskqueue_swi_giant ,
432cb32189eSKenneth D. Merryand
433cb32189eSKenneth D. Merry.Va taskqueue_thread .
4344c49b002SJoseph KoshyThe
4354c49b002SJoseph Koshy.Va taskqueue_fast
4364c49b002SJoseph Koshyqueue is for swi handlers dispatched from fast interrupt handlers,
4374c49b002SJoseph Koshywhere sleep mutexes cannot be used.
438cb32189eSKenneth D. MerryThe swi taskqueues are run via a software interrupt mechanism.
4394c49b002SJoseph KoshyThe
4404c49b002SJoseph Koshy.Va taskqueue_swi
4414c49b002SJoseph Koshyqueue runs without the protection of the
4424c49b002SJoseph Koshy.Va Giant
4434c49b002SJoseph Koshykernel lock, and the
4444c49b002SJoseph Koshy.Va taskqueue_swi_giant
4454c49b002SJoseph Koshyqueue runs with the protection of the
4464c49b002SJoseph Koshy.Va Giant
447cb32189eSKenneth D. Merrykernel lock.
4484c49b002SJoseph KoshyThe thread taskqueue
4494c49b002SJoseph Koshy.Va taskqueue_thread
4504c49b002SJoseph Koshyruns in a kernel thread context, and tasks run from this thread do
4514c49b002SJoseph Koshynot run under the
4524c49b002SJoseph Koshy.Va Giant
4534c49b002SJoseph Koshykernel lock.
4544c49b002SJoseph KoshyIf the caller wants to run under
4554c49b002SJoseph Koshy.Va Giant ,
4564c49b002SJoseph Koshyhe should explicitly acquire and release
4574c49b002SJoseph Koshy.Va Giant
4584c49b002SJoseph Koshyin his taskqueue handler routine.
459bf7f20c2SRuslan Ermilov.Pp
460cb32189eSKenneth D. MerryTo use these queues,
46182323455SDoug Rabsoncall
46282323455SDoug Rabson.Fn taskqueue_enqueue
463cb32189eSKenneth D. Merrywith the value of the global taskqueue variable for the queue you wish to
464c0854fb7SRuslan Ermilovuse
465c0854fb7SRuslan Ermilov.Va ( taskqueue_swi ,
466cb32189eSKenneth D. Merry.Va taskqueue_swi_giant ,
467cb32189eSKenneth D. Merryor
468c0854fb7SRuslan Ermilov.Va taskqueue_thread ) .
4694c49b002SJoseph KoshyUse
4704c49b002SJoseph Koshy.Fn taskqueue_enqueue_fast
4714c49b002SJoseph Koshyfor the global taskqueue variable
4724c49b002SJoseph Koshy.Va taskqueue_fast .
47382323455SDoug Rabson.Pp
474e0254f10SKenneth D. MerryThe software interrupt queues can be used,
47582323455SDoug Rabsonfor instance, for implementing interrupt handlers which must perform a
47682323455SDoug Rabsonsignificant amount of processing in the handler.
47782323455SDoug RabsonThe hardware interrupt handler would perform minimal processing of the
47882323455SDoug Rabsoninterrupt and then enqueue a task to finish the work.
47982323455SDoug RabsonThis reduces to a minimum
48082323455SDoug Rabsonthe amount of time spent with interrupts disabled.
481cb32189eSKenneth D. Merry.Pp
482cb32189eSKenneth D. MerryThe thread queue can be used, for instance, by interrupt level routines
483cb32189eSKenneth D. Merrythat need to call kernel functions that do things that can only be done
484cb32189eSKenneth D. Merryfrom a thread context.
485cb32189eSKenneth D. Merry(e.g., call malloc with the M_WAITOK flag.)
486cf82599dSSam Leffler.Pp
487cf82599dSSam LefflerNote that tasks queued on shared taskqueues such as
488cf82599dSSam Leffler.Va taskqueue_swi
489cf82599dSSam Lefflermay be delayed an indeterminate amount of time before execution.
490cf82599dSSam LefflerIf queueing delays cannot be tolerated then a private taskqueue should
491cf82599dSSam Lefflerbe created with a dedicated processing thread.
4923bbf58f9SJoseph Koshy.Sh SEE ALSO
4933bbf58f9SJoseph Koshy.Xr ithread 9 ,
4943bbf58f9SJoseph Koshy.Xr kthread 9 ,
4953bbf58f9SJoseph Koshy.Xr swi 9
49682323455SDoug Rabson.Sh HISTORY
49782323455SDoug RabsonThis interface first appeared in
49882323455SDoug Rabson.Fx 5.0 .
499c3bd10b4SKonstantin BelousovThere is a similar facility called work_queue in the Linux kernel.
50082323455SDoug Rabson.Sh AUTHORS
501571dba6eSHiten PandyaThis manual page was written by
50282323455SDoug Rabson.An Doug Rabson .
503