1a247c996SSascha Wildner.\" 2a247c996SSascha Wildner.\" Copyright (c) 2000 Doug Rabson 3a247c996SSascha Wildner.\" 4a247c996SSascha Wildner.\" All rights reserved. 5a247c996SSascha Wildner.\" 6a247c996SSascha Wildner.\" This program is free software. 7a247c996SSascha Wildner.\" 8a247c996SSascha Wildner.\" Redistribution and use in source and binary forms, with or without 9a247c996SSascha Wildner.\" modification, are permitted provided that the following conditions 10a247c996SSascha Wildner.\" are met: 11a247c996SSascha Wildner.\" 1. Redistributions of source code must retain the above copyright 12a247c996SSascha Wildner.\" notice, this list of conditions and the following disclaimer. 13a247c996SSascha Wildner.\" 2. Redistributions in binary form must reproduce the above copyright 14a247c996SSascha Wildner.\" notice, this list of conditions and the following disclaimer in the 15a247c996SSascha Wildner.\" documentation and/or other materials provided with the distribution. 16a247c996SSascha Wildner.\" 17a247c996SSascha Wildner.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR 18a247c996SSascha Wildner.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19a247c996SSascha Wildner.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20a247c996SSascha Wildner.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT, 21a247c996SSascha Wildner.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22a247c996SSascha Wildner.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23a247c996SSascha Wildner.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24a247c996SSascha Wildner.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25a247c996SSascha Wildner.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26a247c996SSascha Wildner.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27a247c996SSascha Wildner.\" 28a247c996SSascha Wildner.\" $FreeBSD: src/share/man/man9/taskqueue.9,v 1.21 2007/07/09 06:24:10 jmg Exp $ 29a247c996SSascha Wildner.\" 30*cb24fcd4SSascha Wildner.Dd October 2, 2009 31a247c996SSascha Wildner.Dt TASKQUEUE 9 32a247c996SSascha Wildner.Os 33a247c996SSascha Wildner.Sh NAME 34*cb24fcd4SSascha Wildner.Nm taskqueue_block , 35a247c996SSascha Wildner.Nm taskqueue_create , 36*cb24fcd4SSascha Wildner.Nm tastqueue_drain , 37*cb24fcd4SSascha Wildner.Nm taskqueue_enqueue , 38a247c996SSascha Wildner.Nm taskqueue_free , 39a247c996SSascha Wildner.Nm taskqueue_find , 40a247c996SSascha Wildner.Nm taskqueue_run , 41*cb24fcd4SSascha Wildner.Nm taskqueue_start_threads , 42*cb24fcd4SSascha Wildner.Nm taskqueue_unblock , 43a247c996SSascha Wildner.Nm TASK_INIT , 44a247c996SSascha Wildner.Nm TASKQUEUE_DECLARE , 45a247c996SSascha Wildner.Nm TASKQUEUE_DEFINE 46a247c996SSascha Wildner.Nd asynchronous task execution 47a247c996SSascha Wildner.Sh SYNOPSIS 48a247c996SSascha Wildner.In sys/param.h 49a247c996SSascha Wildner.In sys/kernel.h 50a247c996SSascha Wildner.In sys/malloc.h 51a247c996SSascha Wildner.In sys/queue.h 52a247c996SSascha Wildner.In sys/taskqueue.h 53a247c996SSascha Wildner.Bd -literal 54a247c996SSascha Wildnertypedef void (*task_fn_t)(void *context, int pending); 55a247c996SSascha Wildner 56a247c996SSascha Wildnertypedef void (*taskqueue_enqueue_fn)(void *context); 57a247c996SSascha Wildner 58a247c996SSascha Wildnerstruct task { 59a247c996SSascha Wildner STAILQ_ENTRY(task) ta_link; /* link for queue */ 60a247c996SSascha Wildner int ta_pending; /* count times queued */ 61a247c996SSascha Wildner int ta_priority; /* priority of task in queue */ 62a247c996SSascha Wildner task_fn_t ta_func; /* task handler */ 63a247c996SSascha Wildner void *ta_context; /* argument for handler */ 64a247c996SSascha Wildner}; 65a247c996SSascha Wildner.Ed 66a247c996SSascha Wildner.Ft struct taskqueue * 67a247c996SSascha Wildner.Fn taskqueue_create "const char *name" "int mflags" "taskqueue_enqueue_fn enqueue" "void *context" 68a247c996SSascha Wildner.Ft void 69a247c996SSascha Wildner.Fn taskqueue_free "struct taskqueue *queue" 70a247c996SSascha Wildner.Ft struct taskqueue * 71a247c996SSascha Wildner.Fn taskqueue_find "const char *name" 72a247c996SSascha Wildner.Ft int 73a247c996SSascha Wildner.Fn taskqueue_enqueue "struct taskqueue *queue" "struct task *task" 74a247c996SSascha Wildner.Ft void 75a247c996SSascha Wildner.Fn taskqueue_run "struct taskqueue *queue" 76a0d61755SAlex Hornung.Ft void 77a0d61755SAlex Hornung.Fn taskqueue_drain "struct taskqueue *queue" "struct task *task" 78a0d61755SAlex Hornung.Ft void 79a0d61755SAlex Hornung.Fn taskqueue_block "struct taskqueue *queue" 80a0d61755SAlex Hornung.Ft void 81a0d61755SAlex Hornung.Fn taskqueue_unblock "struct taskqueue *queue" 82a0d61755SAlex Hornung.Ft int 8314ae2e95SAlex Hornung.Fn taskqueue_start_threads "struct taskqueue **tqp" "int count" "int pri" "int ncpu" "const char *fmt" "..." 84a247c996SSascha Wildner.Fn TASK_INIT "struct task *task" "int priority" "task_fn_t *func" "void *context" 85a247c996SSascha Wildner.Fn TASKQUEUE_DECLARE "name" 86a247c996SSascha Wildner.Fn TASKQUEUE_DEFINE "name" "taskqueue_enqueue_fn enqueue" "void *context" "init" 87a247c996SSascha Wildner.Sh DESCRIPTION 88a247c996SSascha WildnerThese functions provide a simple interface for asynchronous execution 89a247c996SSascha Wildnerof code. 90a247c996SSascha Wildner.Pp 91a247c996SSascha WildnerThe function 92a247c996SSascha Wildner.Fn taskqueue_create 93a247c996SSascha Wildneris used to create new queues. 94a247c996SSascha WildnerThe arguments to 95a247c996SSascha Wildner.Fn taskqueue_create 96a247c996SSascha Wildnerinclude a name that should be unique, 97a247c996SSascha Wildnera set of 9887909ed3SSascha Wildner.Xr kmalloc 9 99a247c996SSascha Wildnerflags that specify whether the call to 100a247c996SSascha Wildner.Fn malloc 101a247c996SSascha Wildneris allowed to sleep, 102a247c996SSascha Wildnerand a function which is called from 103a247c996SSascha Wildner.Fn taskqueue_enqueue 104a247c996SSascha Wildnerwhen a task is added to the queue 105a247c996SSascha Wildner.\" XXX The rest of the sentence gets lots in relation to the first part. 106a247c996SSascha Wildnerto allow the queue to arrange to be run later 107a247c996SSascha Wildner(for instance by scheduling a software interrupt or waking a kernel 108a247c996SSascha Wildnerthread). 109a247c996SSascha Wildner.Pp 110a247c996SSascha WildnerThe function 111a247c996SSascha Wildner.Fn taskqueue_free 112a247c996SSascha Wildnershould be used to remove the queue from the global list of queues 113a247c996SSascha Wildnerand free the memory used by the queue. 114a247c996SSascha WildnerAny tasks that are on the queue will be executed at this time. 115a247c996SSascha Wildner.Pp 116a247c996SSascha WildnerThe system maintains a list of all queues which can be searched using 117a247c996SSascha Wildner.Fn taskqueue_find . 118a247c996SSascha WildnerThe first queue whose name matches is returned, otherwise 119a247c996SSascha Wildner.Dv NULL . 120a247c996SSascha Wildner.Pp 121a247c996SSascha WildnerTo add a task to the list of tasks queued on a taskqueue, call 122a247c996SSascha Wildner.Fn taskqueue_enqueue 123a247c996SSascha Wildnerwith pointers to the queue and task. 124a247c996SSascha WildnerIf the task's 125a247c996SSascha Wildner.Fa ta_pending 126a247c996SSascha Wildnerfield is non-zero, 127a247c996SSascha Wildnerthen it is simply incremented to reflect the number of times the task 128a247c996SSascha Wildnerwas enqueued. 129a247c996SSascha WildnerOtherwise, 130a247c996SSascha Wildnerthe task is added to the list before the first task which has a lower 131a247c996SSascha Wildner.Fa ta_priority 132a247c996SSascha Wildnervalue or at the end of the list if no tasks have a lower priority. 133a247c996SSascha WildnerEnqueueing a task does not perform any memory allocation which makes 134a247c996SSascha Wildnerit suitable for calling from an interrupt handler. 135a247c996SSascha WildnerThis function will return 136a247c996SSascha Wildner.Er EPIPE 137a247c996SSascha Wildnerif the queue is being freed. 138a247c996SSascha Wildner.Pp 139a247c996SSascha WildnerTo execute all the tasks on a queue, 140a247c996SSascha Wildnercall 141a247c996SSascha Wildner.Fn taskqueue_run . 142a247c996SSascha WildnerWhen a task is executed, 143a247c996SSascha Wildnerfirst it is removed from the queue, 144a247c996SSascha Wildnerthe value of 145a247c996SSascha Wildner.Fa ta_pending 146a247c996SSascha Wildneris recorded and then the field is zeroed. 147a247c996SSascha WildnerThe function 148a247c996SSascha Wildner.Fa ta_func 149a247c996SSascha Wildnerfrom the task structure is called with the value of the field 150a247c996SSascha Wildner.Fa ta_context 151a247c996SSascha Wildneras its first argument 152a247c996SSascha Wildnerand the value of 153a247c996SSascha Wildner.Fa ta_pending 154a247c996SSascha Wildneras its second argument. 155a247c996SSascha Wildner.Pp 156a0d61755SAlex HornungThe 157a0d61755SAlex Hornung.Fn taskqueue_drain 158a0d61755SAlex Hornungfunction is used to wait for the task to finish. 159a0d61755SAlex HornungThere is no guarantee that the task will not be 160a0d61755SAlex Hornungenqueued after call to 161a0d61755SAlex Hornung.Fn taskqueue_drain . 162a0d61755SAlex Hornung.Pp 163a0d61755SAlex HornungThe 164a0d61755SAlex Hornung.Fn taskqueue_block 165*cb24fcd4SSascha Wildnerfunction is used to block a taskqueue. 166*cb24fcd4SSascha WildnerWhen a taskqueue is blocked, calls to 167*cb24fcd4SSascha Wildner.Fn taskqueue_enqueue 168*cb24fcd4SSascha Wildnerwill still enqueue tasks but 169*cb24fcd4SSascha Wildnerthey will not be run until the taskqueue is unblocked by calling 170a0d61755SAlex Hornung.Fn taskqueue_unblock . 171a0d61755SAlex Hornung.Pp 172a0d61755SAlex HornungThe 173a0d61755SAlex Hornung.Fn taskqueue_start_threads 174a0d61755SAlex Hornungfunction is used to create and start 175a0d61755SAlex Hornung.Fa count 176a0d61755SAlex Hornungdedicated threads for the taskqueue specified by 177a0d61755SAlex Hornung.Fa tqp . 178a0d61755SAlex HornungThese threads will be created with the priority specified by 179a0d61755SAlex Hornung.Fa pri 180a0d61755SAlex Hornungand the name given by 181a0d61755SAlex Hornung.Fa fmt 182a0d61755SAlex Hornungwith _N appended to it, where N is the number of the thread. 18314ae2e95SAlex HornungIf 18414ae2e95SAlex Hornung.Fa count 185*cb24fcd4SSascha Wildner\*(Gt 1 and 18614ae2e95SAlex Hornung.Fa ncpu 18714ae2e95SAlex Hornungis -1, each of the 18814ae2e95SAlex Hornung.Fa count 18914ae2e95SAlex Hornungthreads will be allocated to a different 19014ae2e95SAlex HornungCPU among all available CPUs in a round robin fashion. 191a0d61755SAlex HornungThe taskqueue specified by 192a0d61755SAlex Hornung.Fa tqp 193a0d61755SAlex Hornungmust be created previously by calling 194a0d61755SAlex Hornung.Fn taskqueue_create 195a0d61755SAlex Hornungwith the argument 196a0d61755SAlex Hornung.Fa enqueue 197a0d61755SAlex Hornungset to 198a0d61755SAlex Hornung.Fa taskqueue_thread_enqueue . 199a0d61755SAlex Hornung.Pp 200a247c996SSascha WildnerA convenience macro, 201a247c996SSascha Wildner.Fn TASK_INIT 202a247c996SSascha Wildneris provided to initialise a 203a247c996SSascha Wildner.Vt task 204a247c996SSascha Wildnerstructure. 205a247c996SSascha WildnerThe values of 206a247c996SSascha Wildner.Fa priority , 207a247c996SSascha Wildner.Fa func , 208a247c996SSascha Wildnerand 209a247c996SSascha Wildner.Fa context 210a247c996SSascha Wildnerare simply copied into the task structure fields and the 211a247c996SSascha Wildner.Fa ta_pending 212a247c996SSascha Wildnerfield is cleared. 213a247c996SSascha Wildner.Pp 214a247c996SSascha WildnerTwo macros, 215a247c996SSascha Wildner.Fn TASKQUEUE_DECLARE 216a247c996SSascha Wildnerand 217a247c996SSascha Wildner.Fn TASKQUEUE_DEFINE 218a247c996SSascha Wildnerare used to declare a reference to a global queue, 219a247c996SSascha Wildnerand to define the implementation of the queue. 220a247c996SSascha WildnerThe 221a247c996SSascha Wildner.Fn TASKQUEUE_DEFINE 222a247c996SSascha Wildnermacro arranges to call 223a247c996SSascha Wildner.Fn taskqueue_create 224a247c996SSascha Wildnerwith the values of its 225a247c996SSascha Wildner.Fa name , 226a247c996SSascha Wildner.Fa enqueue 227a247c996SSascha Wildnerand 228a247c996SSascha Wildner.Fa context 229a247c996SSascha Wildnerarguments during system initialisation. 230a247c996SSascha WildnerAfter calling 231a247c996SSascha Wildner.Fn taskqueue_create , 232a247c996SSascha Wildnerthe 233a247c996SSascha Wildner.Fa init 234a247c996SSascha Wildnerargument to the macro is executed as a C statement, 235a247c996SSascha Wildnerallowing any further initialisation to be performed 236a247c996SSascha Wildner(such as registering an interrupt handler etc.) 237a247c996SSascha Wildner.Pp 238a0d61755SAlex HornungThe system provides two global taskqueues, 239*cb24fcd4SSascha Wildner.Va taskqueue_swi 240*cb24fcd4SSascha Wildnerand 241a0d61755SAlex Hornung.Va taskqueue_swi_mp , 242a0d61755SAlex Hornungwhich are run via a software interrupt mechanism. 243a0d61755SAlex HornungTo use these queues, call 244a247c996SSascha Wildner.Fn taskqueue_enqueue 245a247c996SSascha Wildnerwith the value of the global variable 246*cb24fcd4SSascha Wildner.Va taskqueue_swi 247*cb24fcd4SSascha Wildneror 248a0d61755SAlex Hornung.Va taskqueue_swi_mp . 249a247c996SSascha Wildner.Pp 250a0d61755SAlex HornungWhile 251a0d61755SAlex Hornung.Va taskqueue_swi 252a0d61755SAlex Hornungacquires the mplock for its tasks, 253a0d61755SAlex Hornung.Va taskqueue_swi_mp 254a0d61755SAlex Hornungis intended for mpsafe tasks and no mplock will be acquired for them. 255a0d61755SAlex HornungThese queues can be used, 256a247c996SSascha Wildnerfor instance, for implementing interrupt handlers which must perform a 257a247c996SSascha Wildnersignificant amount of processing in the handler. 258a247c996SSascha WildnerThe hardware interrupt handler would perform minimal processing of the 259a247c996SSascha Wildnerinterrupt and then enqueue a task to finish the work. 260a247c996SSascha WildnerThis reduces to a minimum 261a247c996SSascha Wildnerthe amount of time spent with interrupts disabled. 262a247c996SSascha Wildner.\".Sh SEE ALSO 263a247c996SSascha Wildner.\".Xr ithread 9 , 264a247c996SSascha Wildner.\".Xr kthread 9 , 265a247c996SSascha Wildner.\".Xr swi 9 266a247c996SSascha Wildner.Sh HISTORY 267a247c996SSascha WildnerThis interface first appeared in 268a247c996SSascha Wildner.Fx 5.0 . 269a247c996SSascha WildnerThere is a similar facility called tqueue in the Linux kernel. 270a247c996SSascha Wildner.Sh AUTHORS 271a247c996SSascha WildnerThis manual page was written by 272a247c996SSascha Wildner.An Doug Rabson . 273