xref: /freebsd/share/man/man9/taskqueue.9 (revision f16b3c0de48d0b845357e7cca843f645bc3117e3)
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.\"
3182323455SDoug Rabson.Dd May 12, 2000
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
4482323455SDoug Rabson
4582323455SDoug Rabsontypedef void (*task_fn)(void *context, int pending);
4682323455SDoug Rabson
4782323455SDoug Rabsontypedef void (*taskqueue_enqueue_fn)(void *context);
4882323455SDoug Rabson
4982323455SDoug Rabsonstruct task {
5082323455SDoug Rabson	STAILQ_ENTRY(task)	ta_link;	/* link for queue */
5182323455SDoug Rabson	int			ta_pending;	/* count times queued */
5282323455SDoug Rabson	int			ta_priority;	/* priority of task in queue */
5382323455SDoug Rabson	task_fn			ta_func;	/* task handler */
5482323455SDoug Rabson	void			*ta_context;	/* argument for handler */
5582323455SDoug Rabson};
5682323455SDoug Rabson
5782323455SDoug Rabson.Ed
5882323455SDoug Rabson.Ft struct taskqueue *
5982323455SDoug Rabson.Fn taskqueue_create "const char *name" "int mflags" "taskqueue_enqueue_fn enqueue" "void *context"
6082323455SDoug Rabson.Ft void
6182323455SDoug Rabson.Fn taskqueue_free "struct taskqueue *queue"
6282323455SDoug Rabson.Ft struct taskqueue *
6382323455SDoug Rabson.Fn taskqueue_find "const char *name"
6482323455SDoug Rabson.Ft int
6582323455SDoug Rabson.Fn taskqueue_enqueue "struct taskqueue *queue" "struct task *task"
6682323455SDoug Rabson.Ft void
6782323455SDoug Rabson.Fn taskqueue_run "struct taskqueue *queue"
68f16b3c0dSChad David.Fn TASK_INIT "struct task *task" "int priority" "task_fn_t *func" "void *context"
6982323455SDoug Rabson.Fn TASKQUEUE_DECLARE "name"
70f16b3c0dSChad David.Fn TASKQUEUE_DEFINE "name" "taskqueue_enqueue_fn enqueue" "void *context" "init"
7182323455SDoug Rabson.Sh DESCRIPTION
7282323455SDoug RabsonThese functions provide a simple interface for asynchronous execution
7382323455SDoug Rabsonof code.
7482323455SDoug Rabson.Pp
7582323455SDoug RabsonThe function
7682323455SDoug Rabson.Fn taskqueue_create
7782323455SDoug Rabsonis used to create new queues.
7882323455SDoug RabsonThe arguments to
7982323455SDoug Rabson.Fn taskqueue_create
8082323455SDoug Rabsoninclude a name which should be unique,
8182323455SDoug Rabsona set of
8282323455SDoug Rabson.Xr malloc 9
8382323455SDoug Rabsonflags which specify whether the call to
8482323455SDoug Rabson.Fn malloc
8582323455SDoug Rabsonis allowed to sleep
8682323455SDoug Rabsonand a function which is called from
8782323455SDoug Rabson.Fn taskqueue_enqueue
8882323455SDoug Rabsonwhen a task is added to the queue
8982323455SDoug Rabson.\" XXX	The rest of the sentence gets lots in relation to the first part.
9082323455SDoug Rabsonto allow the queue to arrange to be run later
9182323455SDoug Rabson(for instance by scheduling a software interrupt or waking a kernel
9282323455SDoug Rabsonthread).
9382323455SDoug Rabson.Pp
9482323455SDoug RabsonThe function
9582323455SDoug Rabson.Fn taskqueue_free
9682323455SDoug Rabsonshould be used to remove the queue from the global list of queues
9782323455SDoug Rabsonand free the memory used by the queue.
9882323455SDoug RabsonAny tasks which are on the queue will be executed at this time.
9982323455SDoug Rabson.Pp
10082323455SDoug RabsonThe system maintains a list of all queues which can be searched using
10182323455SDoug Rabson.Fn taskqueue_find .
10282323455SDoug RabsonThe first queue whose name matches is returned, otherwise
10382323455SDoug Rabson.Dv NULL .
10482323455SDoug Rabson.Pp
10582323455SDoug RabsonTo add a task to the list of tasks queued on a taskqueue, call
10682323455SDoug Rabson.Fn taskqueue_enqueue
10782323455SDoug Rabsonwith pointers to the queue and task.
10882323455SDoug RabsonIf the task's
10982323455SDoug Rabson.Va ta_pending
11082323455SDoug Rabsonfield is non-zero,
11182323455SDoug Rabsonthen it is simply incremented to reflect the number of times the task
11282323455SDoug Rabsonwas enqueued.
11382323455SDoug RabsonOtherwise,
11482323455SDoug Rabsonthe task is added to the list before the first task which has a lower
11582323455SDoug Rabson.Va ta_priority
11682323455SDoug Rabsonvalue or at the end of the list if no tasks have a lower priority.
11782323455SDoug RabsonEnqueueing a task does not perform any memory allocation which makes
11882323455SDoug Rabsonit suitable for calling from an interrupt handler.
11982323455SDoug RabsonThis function will return
120b92a189eSRuslan Ermilov.Er EPIPE
12182323455SDoug Rabsonif the queue is being freed.
12282323455SDoug Rabson.Pp
12382323455SDoug RabsonTo execute all the tasks on a queue,
12482323455SDoug Rabsoncall
12582323455SDoug Rabson.Fn taskqueue_run .
12682323455SDoug RabsonWhen a task is executed,
12782323455SDoug Rabsonfirst it is removed from the queue,
12882323455SDoug Rabsonthe value of
12982323455SDoug Rabson.Va ta_pending
13082323455SDoug Rabsonis recorded and then the field is zeroed.
13182323455SDoug RabsonThe function
13282323455SDoug Rabson.Va ta_func
13382323455SDoug Rabsonfrom the task structure is called with the value of the field
13482323455SDoug Rabson.Va ta_context
13582323455SDoug Rabsonas its first argument
13682323455SDoug Rabsonand the value of
13782323455SDoug Rabson.Va ta_pending
13882323455SDoug Rabsonas its second argument.
13982323455SDoug Rabson.Pp
14082323455SDoug RabsonA convenience macro,
14182323455SDoug Rabson.Fn TASK_INIT "task" "priority" "func" "context"
14282323455SDoug Rabsonis provided to initialise a
14382323455SDoug Rabson.Va task
14482323455SDoug Rabsonstructure.
14582323455SDoug RabsonThe values of
14682323455SDoug Rabson.Va priority ,
14782323455SDoug Rabson.Va func ,
14882323455SDoug Rabsonand
14982323455SDoug Rabson.Va context
15082323455SDoug Rabsonare simply copied into the task structure fields and the
15182323455SDoug Rabson.Va ta_pending
15282323455SDoug Rabsonfield is cleared.
15382323455SDoug Rabson.Pp
15482323455SDoug RabsonTwo macros
15582323455SDoug Rabson.Fn TASKQUEUE_DECLARE "name"
15682323455SDoug Rabsonand
15782323455SDoug Rabson.Fn TASKQUEUE_DEFINE "name" "enqueue" "context" "init"
15882323455SDoug Rabsonare used to declare a reference to a global queue
15982323455SDoug Rabsonand to define the implementation of the queue.
16082323455SDoug RabsonThe
16182323455SDoug Rabson.Fn TASKQUEUE_DEFINE
16282323455SDoug Rabsonmacro arranges to call
16382323455SDoug Rabson.Fn taskqueue_create
16482323455SDoug Rabsonwith the values of its
16582323455SDoug Rabson.Va name ,
16682323455SDoug Rabson.Va enqueue
16782323455SDoug Rabsonand
16882323455SDoug Rabson.Va context
16982323455SDoug Rabsonarguments during system initialisation.
17082323455SDoug RabsonAfter calling
17182323455SDoug Rabson.Fn taskqueue_create ,
17282323455SDoug Rabsonthe
17382323455SDoug Rabson.Va init
17482323455SDoug Rabsonargument to the macro is executed as a C statement,
17582323455SDoug Rabsonallowing any further initialisation to be performed
17682323455SDoug Rabson(such as registering an interrupt handler etc.)
17782323455SDoug Rabson.Pp
17882323455SDoug RabsonThe system provides a global taskqueue,
17982323455SDoug Rabson.Va taskqueue_swi ,
18082323455SDoug Rabsonwhich is run via a software interrupt mechanism.
18182323455SDoug RabsonTo use this queue,
18282323455SDoug Rabsoncall
18382323455SDoug Rabson.Fn taskqueue_enqueue
18482323455SDoug Rabsonwith the value of the global variable
18582323455SDoug Rabson.Va taskqueue_swi .
18682323455SDoug RabsonThe queue will be run at
18782323455SDoug Rabson.\" XXX	This should be a cross-reference (Xr), but there is no MANLINKS
18882323455SDoug Rabson.\"	entry for splsofttq.9 yet.
18982323455SDoug Rabson.Fn splsofttq .
19082323455SDoug Rabson.Pp
19182323455SDoug RabsonThis queue can be used,
19282323455SDoug Rabsonfor instance, for implementing interrupt handlers which must perform a
19382323455SDoug Rabsonsignificant amount of processing in the handler.
19482323455SDoug RabsonThe hardware interrupt handler would perform minimal processing of the
19582323455SDoug Rabsoninterrupt and then enqueue a task to finish the work.
19682323455SDoug RabsonThis reduces to a minimum
19782323455SDoug Rabsonthe amount of time spent with interrupts disabled.
19882323455SDoug Rabson.Sh HISTORY
19982323455SDoug RabsonThis interface first appeared in
20082323455SDoug Rabson.Fx 5.0 .
20182323455SDoug RabsonThere is a similar facility called tqueue in the Linux kernel.
20282323455SDoug Rabson.Sh AUTHORS
20382323455SDoug RabsonThis man page was written by
20482323455SDoug Rabson.An Doug Rabson .
205