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