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