.\" .\" Copyright (c) 2000 Doug Rabson .\" .\" All rights reserved. .\" .\" This program is free software. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR .\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES .\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. .\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT, .\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT .\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, .\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY .\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" .\" $FreeBSD: src/share/man/man9/taskqueue.9,v 1.21 2007/07/09 06:24:10 jmg Exp $ .\" $DragonFly: src/share/man/man9/taskqueue.9,v 1.2 2007/11/07 21:38:00 swildner Exp $ .\" .Dd August 10, 2007 .Dt TASKQUEUE 9 .Os .Sh NAME .Nm taskqueue_create , .Nm taskqueue_free , .Nm taskqueue_find , .Nm taskqueue_enqueue , .Nm taskqueue_run , .Nm TASK_INIT , .Nm TASKQUEUE_DECLARE , .Nm TASKQUEUE_DEFINE .Nd asynchronous task execution .Sh SYNOPSIS .In sys/param.h .In sys/kernel.h .In sys/malloc.h .In sys/queue.h .In sys/taskqueue.h .Bd -literal typedef void (*task_fn_t)(void *context, int pending); typedef void (*taskqueue_enqueue_fn)(void *context); struct task { STAILQ_ENTRY(task) ta_link; /* link for queue */ int ta_pending; /* count times queued */ int ta_priority; /* priority of task in queue */ task_fn_t ta_func; /* task handler */ void *ta_context; /* argument for handler */ }; .Ed .Ft struct taskqueue * .Fn taskqueue_create "const char *name" "int mflags" "taskqueue_enqueue_fn enqueue" "void *context" .Ft void .Fn taskqueue_free "struct taskqueue *queue" .Ft struct taskqueue * .Fn taskqueue_find "const char *name" .Ft int .Fn taskqueue_enqueue "struct taskqueue *queue" "struct task *task" .Ft void .Fn taskqueue_run "struct taskqueue *queue" .Fn TASK_INIT "struct task *task" "int priority" "task_fn_t *func" "void *context" .Fn TASKQUEUE_DECLARE "name" .Fn TASKQUEUE_DEFINE "name" "taskqueue_enqueue_fn enqueue" "void *context" "init" .Sh DESCRIPTION These functions provide a simple interface for asynchronous execution of code. .Pp The function .Fn taskqueue_create is used to create new queues. The arguments to .Fn taskqueue_create include a name that should be unique, a set of .Xr kmalloc 9 flags that specify whether the call to .Fn malloc is allowed to sleep, and a function which is called from .Fn taskqueue_enqueue when a task is added to the queue .\" XXX The rest of the sentence gets lots in relation to the first part. to allow the queue to arrange to be run later (for instance by scheduling a software interrupt or waking a kernel thread). .Pp The function .Fn taskqueue_free should be used to remove the queue from the global list of queues and free the memory used by the queue. Any tasks that are on the queue will be executed at this time. .Pp The system maintains a list of all queues which can be searched using .Fn taskqueue_find . The first queue whose name matches is returned, otherwise .Dv NULL . .Pp To add a task to the list of tasks queued on a taskqueue, call .Fn taskqueue_enqueue with pointers to the queue and task. If the task's .Fa ta_pending field is non-zero, then it is simply incremented to reflect the number of times the task was enqueued. Otherwise, the task is added to the list before the first task which has a lower .Fa ta_priority value or at the end of the list if no tasks have a lower priority. Enqueueing a task does not perform any memory allocation which makes it suitable for calling from an interrupt handler. This function will return .Er EPIPE if the queue is being freed. .Pp To execute all the tasks on a queue, call .Fn taskqueue_run . When a task is executed, first it is removed from the queue, the value of .Fa ta_pending is recorded and then the field is zeroed. The function .Fa ta_func from the task structure is called with the value of the field .Fa ta_context as its first argument and the value of .Fa ta_pending as its second argument. .Pp A convenience macro, .Fn TASK_INIT is provided to initialise a .Vt task structure. The values of .Fa priority , .Fa func , and .Fa context are simply copied into the task structure fields and the .Fa ta_pending field is cleared. .Pp Two macros, .Fn TASKQUEUE_DECLARE and .Fn TASKQUEUE_DEFINE are used to declare a reference to a global queue, and to define the implementation of the queue. The .Fn TASKQUEUE_DEFINE macro arranges to call .Fn taskqueue_create with the values of its .Fa name , .Fa enqueue and .Fa context arguments during system initialisation. After calling .Fn taskqueue_create , the .Fa init argument to the macro is executed as a C statement, allowing any further initialisation to be performed (such as registering an interrupt handler etc.) .Pp The system provides a global taskqueue, .Va taskqueue_swi , which is run via a software interrupt mechanism. To use this queue, call .Fn taskqueue_enqueue with the value of the global variable .Va taskqueue_swi . .Pp This queue can be used, for instance, for implementing interrupt handlers which must perform a significant amount of processing in the handler. The hardware interrupt handler would perform minimal processing of the interrupt and then enqueue a task to finish the work. This reduces to a minimum the amount of time spent with interrupts disabled. .\".Sh SEE ALSO .\".Xr ithread 9 , .\".Xr kthread 9 , .\".Xr swi 9 .Sh HISTORY This interface first appeared in .Fx 5.0 . There is a similar facility called tqueue in the Linux kernel. .Sh AUTHORS This manual page was written by .An Doug Rabson .