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.Ft void 74.Fn taskqueue_drain "struct taskqueue *queue" "struct task *task" 75.Ft void 76.Fn taskqueue_block "struct taskqueue *queue" 77.Ft void 78.Fn taskqueue_unblock "struct taskqueue *queue" 79.Ft int 80.Fn taskqueue_start_threads "struct taskqueue **tqp" "int count" "int pri" "int ncpu" "const char *fmt" "..." 81.Fn TASK_INIT "struct task *task" "int priority" "task_fn_t *func" "void *context" 82.Fn TASKQUEUE_DECLARE "name" 83.Fn TASKQUEUE_DEFINE "name" "taskqueue_enqueue_fn enqueue" "void *context" "init" 84.Sh DESCRIPTION 85These functions provide a simple interface for asynchronous execution 86of code. 87.Pp 88The function 89.Fn taskqueue_create 90is used to create new queues. 91The arguments to 92.Fn taskqueue_create 93include a name that should be unique, 94a set of 95.Xr kmalloc 9 96flags that specify whether the call to 97.Fn malloc 98is allowed to sleep, 99and a function which is called from 100.Fn taskqueue_enqueue 101when a task is added to the queue 102.\" XXX The rest of the sentence gets lots in relation to the first part. 103to allow the queue to arrange to be run later 104(for instance by scheduling a software interrupt or waking a kernel 105thread). 106.Pp 107The function 108.Fn taskqueue_free 109should be used to remove the queue from the global list of queues 110and free the memory used by the queue. 111Any tasks that are on the queue will be executed at this time. 112.Pp 113The system maintains a list of all queues which can be searched using 114.Fn taskqueue_find . 115The first queue whose name matches is returned, otherwise 116.Dv NULL . 117.Pp 118To add a task to the list of tasks queued on a taskqueue, call 119.Fn taskqueue_enqueue 120with pointers to the queue and task. 121If the task's 122.Fa ta_pending 123field is non-zero, 124then it is simply incremented to reflect the number of times the task 125was enqueued. 126Otherwise, 127the task is added to the list before the first task which has a lower 128.Fa ta_priority 129value or at the end of the list if no tasks have a lower priority. 130Enqueueing a task does not perform any memory allocation which makes 131it suitable for calling from an interrupt handler. 132This function will return 133.Er EPIPE 134if the queue is being freed. 135.Pp 136To execute all the tasks on a queue, 137call 138.Fn taskqueue_run . 139When a task is executed, 140first it is removed from the queue, 141the value of 142.Fa ta_pending 143is recorded and then the field is zeroed. 144The function 145.Fa ta_func 146from the task structure is called with the value of the field 147.Fa ta_context 148as its first argument 149and the value of 150.Fa ta_pending 151as its second argument. 152.Pp 153The 154.Fn taskqueue_drain 155function is used to wait for the task to finish. 156There is no guarantee that the task will not be 157enqueued after call to 158.Fn taskqueue_drain . 159.Pp 160The 161.Fn taskqueue_block 162function is used to block a taskqueue. When a taskqueue 163is blocked, calls to enqueue will still enqueue tasks but 164they will not be run until the taskqueue is unblocked by 165calling 166.Fn taskqueue_unblock . 167.Pp 168The 169.Fn taskqueue_start_threads 170function is used to create and start 171.Fa count 172dedicated threads for the taskqueue specified by 173.Fa tqp . 174These threads will be created with the priority specified by 175.Fa pri 176and the name given by 177.Fa fmt 178with _N appended to it, where N is the number of the thread. 179If 180.Fa count 181 > 1 and 182.Fa ncpu 183is -1, each of the 184.Fa count 185threads will be allocated to a different 186CPU among all available CPUs in a round robin fashion. 187The taskqueue specified by 188.Fa tqp 189must be created previously by calling 190.Fn taskqueue_create 191with the argument 192.Fa enqueue 193set to 194.Fa taskqueue_thread_enqueue . 195.Pp 196A convenience macro, 197.Fn TASK_INIT 198is provided to initialise a 199.Vt task 200structure. 201The values of 202.Fa priority , 203.Fa func , 204and 205.Fa context 206are simply copied into the task structure fields and the 207.Fa ta_pending 208field is cleared. 209.Pp 210Two macros, 211.Fn TASKQUEUE_DECLARE 212and 213.Fn TASKQUEUE_DEFINE 214are used to declare a reference to a global queue, 215and to define the implementation of the queue. 216The 217.Fn TASKQUEUE_DEFINE 218macro arranges to call 219.Fn taskqueue_create 220with the values of its 221.Fa name , 222.Fa enqueue 223and 224.Fa context 225arguments during system initialisation. 226After calling 227.Fn taskqueue_create , 228the 229.Fa init 230argument to the macro is executed as a C statement, 231allowing any further initialisation to be performed 232(such as registering an interrupt handler etc.) 233.Pp 234The system provides two global taskqueues, 235.Va taskqueue_swi , 236.Va taskqueue_swi_mp , 237which are run via a software interrupt mechanism. 238To use these queues, call 239.Fn taskqueue_enqueue 240with the value of the global variable 241.Va taskqueue_swi or 242.Va taskqueue_swi_mp . 243.Pp 244While 245.Va taskqueue_swi 246acquires the mplock for its tasks, 247.Va taskqueue_swi_mp 248is intended for mpsafe tasks and no mplock will be acquired for them. 249These queues can be used, 250for instance, for implementing interrupt handlers which must perform a 251significant amount of processing in the handler. 252The hardware interrupt handler would perform minimal processing of the 253interrupt and then enqueue a task to finish the work. 254This reduces to a minimum 255the amount of time spent with interrupts disabled. 256.\".Sh SEE ALSO 257.\".Xr ithread 9 , 258.\".Xr kthread 9 , 259.\".Xr swi 9 260.Sh HISTORY 261This interface first appeared in 262.Fx 5.0 . 263There is a similar facility called tqueue in the Linux kernel. 264.Sh AUTHORS 265This manual page was written by 266.An Doug Rabson . 267