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 $ 29*87909ed3SSascha Wildner.\" $DragonFly: src/share/man/man9/taskqueue.9,v 1.2 2007/11/07 21:38:00 swildner Exp $ 30a247c996SSascha Wildner.\" 31a247c996SSascha Wildner.Dd August 10, 2007 32a247c996SSascha Wildner.Dt TASKQUEUE 9 33a247c996SSascha Wildner.Os 34a247c996SSascha Wildner.Sh NAME 35a247c996SSascha Wildner.Nm taskqueue_create , 36a247c996SSascha Wildner.Nm taskqueue_free , 37a247c996SSascha Wildner.Nm taskqueue_find , 38a247c996SSascha Wildner.Nm taskqueue_enqueue , 39a247c996SSascha Wildner.Nm taskqueue_run , 40a247c996SSascha Wildner.Nm TASK_INIT , 41a247c996SSascha Wildner.Nm TASKQUEUE_DECLARE , 42a247c996SSascha Wildner.Nm TASKQUEUE_DEFINE 43a247c996SSascha Wildner.Nd asynchronous task execution 44a247c996SSascha Wildner.Sh SYNOPSIS 45a247c996SSascha Wildner.In sys/param.h 46a247c996SSascha Wildner.In sys/kernel.h 47a247c996SSascha Wildner.In sys/malloc.h 48a247c996SSascha Wildner.In sys/queue.h 49a247c996SSascha Wildner.In sys/taskqueue.h 50a247c996SSascha Wildner.Bd -literal 51a247c996SSascha Wildnertypedef void (*task_fn_t)(void *context, int pending); 52a247c996SSascha Wildner 53a247c996SSascha Wildnertypedef void (*taskqueue_enqueue_fn)(void *context); 54a247c996SSascha Wildner 55a247c996SSascha Wildnerstruct task { 56a247c996SSascha Wildner STAILQ_ENTRY(task) ta_link; /* link for queue */ 57a247c996SSascha Wildner int ta_pending; /* count times queued */ 58a247c996SSascha Wildner int ta_priority; /* priority of task in queue */ 59a247c996SSascha Wildner task_fn_t ta_func; /* task handler */ 60a247c996SSascha Wildner void *ta_context; /* argument for handler */ 61a247c996SSascha Wildner}; 62a247c996SSascha Wildner.Ed 63a247c996SSascha Wildner.Ft struct taskqueue * 64a247c996SSascha Wildner.Fn taskqueue_create "const char *name" "int mflags" "taskqueue_enqueue_fn enqueue" "void *context" 65a247c996SSascha Wildner.Ft void 66a247c996SSascha Wildner.Fn taskqueue_free "struct taskqueue *queue" 67a247c996SSascha Wildner.Ft struct taskqueue * 68a247c996SSascha Wildner.Fn taskqueue_find "const char *name" 69a247c996SSascha Wildner.Ft int 70a247c996SSascha Wildner.Fn taskqueue_enqueue "struct taskqueue *queue" "struct task *task" 71a247c996SSascha Wildner.Ft void 72a247c996SSascha Wildner.Fn taskqueue_run "struct taskqueue *queue" 73a247c996SSascha Wildner.Fn TASK_INIT "struct task *task" "int priority" "task_fn_t *func" "void *context" 74a247c996SSascha Wildner.Fn TASKQUEUE_DECLARE "name" 75a247c996SSascha Wildner.Fn TASKQUEUE_DEFINE "name" "taskqueue_enqueue_fn enqueue" "void *context" "init" 76a247c996SSascha Wildner.Sh DESCRIPTION 77a247c996SSascha WildnerThese functions provide a simple interface for asynchronous execution 78a247c996SSascha Wildnerof code. 79a247c996SSascha Wildner.Pp 80a247c996SSascha WildnerThe function 81a247c996SSascha Wildner.Fn taskqueue_create 82a247c996SSascha Wildneris used to create new queues. 83a247c996SSascha WildnerThe arguments to 84a247c996SSascha Wildner.Fn taskqueue_create 85a247c996SSascha Wildnerinclude a name that should be unique, 86a247c996SSascha Wildnera set of 87*87909ed3SSascha Wildner.Xr kmalloc 9 88a247c996SSascha Wildnerflags that specify whether the call to 89a247c996SSascha Wildner.Fn malloc 90a247c996SSascha Wildneris allowed to sleep, 91a247c996SSascha Wildnerand a function which is called from 92a247c996SSascha Wildner.Fn taskqueue_enqueue 93a247c996SSascha Wildnerwhen a task is added to the queue 94a247c996SSascha Wildner.\" XXX The rest of the sentence gets lots in relation to the first part. 95a247c996SSascha Wildnerto allow the queue to arrange to be run later 96a247c996SSascha Wildner(for instance by scheduling a software interrupt or waking a kernel 97a247c996SSascha Wildnerthread). 98a247c996SSascha Wildner.Pp 99a247c996SSascha WildnerThe function 100a247c996SSascha Wildner.Fn taskqueue_free 101a247c996SSascha Wildnershould be used to remove the queue from the global list of queues 102a247c996SSascha Wildnerand free the memory used by the queue. 103a247c996SSascha WildnerAny tasks that are on the queue will be executed at this time. 104a247c996SSascha Wildner.Pp 105a247c996SSascha WildnerThe system maintains a list of all queues which can be searched using 106a247c996SSascha Wildner.Fn taskqueue_find . 107a247c996SSascha WildnerThe first queue whose name matches is returned, otherwise 108a247c996SSascha Wildner.Dv NULL . 109a247c996SSascha Wildner.Pp 110a247c996SSascha WildnerTo add a task to the list of tasks queued on a taskqueue, call 111a247c996SSascha Wildner.Fn taskqueue_enqueue 112a247c996SSascha Wildnerwith pointers to the queue and task. 113a247c996SSascha WildnerIf the task's 114a247c996SSascha Wildner.Fa ta_pending 115a247c996SSascha Wildnerfield is non-zero, 116a247c996SSascha Wildnerthen it is simply incremented to reflect the number of times the task 117a247c996SSascha Wildnerwas enqueued. 118a247c996SSascha WildnerOtherwise, 119a247c996SSascha Wildnerthe task is added to the list before the first task which has a lower 120a247c996SSascha Wildner.Fa ta_priority 121a247c996SSascha Wildnervalue or at the end of the list if no tasks have a lower priority. 122a247c996SSascha WildnerEnqueueing a task does not perform any memory allocation which makes 123a247c996SSascha Wildnerit suitable for calling from an interrupt handler. 124a247c996SSascha WildnerThis function will return 125a247c996SSascha Wildner.Er EPIPE 126a247c996SSascha Wildnerif the queue is being freed. 127a247c996SSascha Wildner.Pp 128a247c996SSascha WildnerTo execute all the tasks on a queue, 129a247c996SSascha Wildnercall 130a247c996SSascha Wildner.Fn taskqueue_run . 131a247c996SSascha WildnerWhen a task is executed, 132a247c996SSascha Wildnerfirst it is removed from the queue, 133a247c996SSascha Wildnerthe value of 134a247c996SSascha Wildner.Fa ta_pending 135a247c996SSascha Wildneris recorded and then the field is zeroed. 136a247c996SSascha WildnerThe function 137a247c996SSascha Wildner.Fa ta_func 138a247c996SSascha Wildnerfrom the task structure is called with the value of the field 139a247c996SSascha Wildner.Fa ta_context 140a247c996SSascha Wildneras its first argument 141a247c996SSascha Wildnerand the value of 142a247c996SSascha Wildner.Fa ta_pending 143a247c996SSascha Wildneras its second argument. 144a247c996SSascha Wildner.Pp 145a247c996SSascha WildnerA convenience macro, 146a247c996SSascha Wildner.Fn TASK_INIT 147a247c996SSascha Wildneris provided to initialise a 148a247c996SSascha Wildner.Vt task 149a247c996SSascha Wildnerstructure. 150a247c996SSascha WildnerThe values of 151a247c996SSascha Wildner.Fa priority , 152a247c996SSascha Wildner.Fa func , 153a247c996SSascha Wildnerand 154a247c996SSascha Wildner.Fa context 155a247c996SSascha Wildnerare simply copied into the task structure fields and the 156a247c996SSascha Wildner.Fa ta_pending 157a247c996SSascha Wildnerfield is cleared. 158a247c996SSascha Wildner.Pp 159a247c996SSascha WildnerTwo macros, 160a247c996SSascha Wildner.Fn TASKQUEUE_DECLARE 161a247c996SSascha Wildnerand 162a247c996SSascha Wildner.Fn TASKQUEUE_DEFINE 163a247c996SSascha Wildnerare used to declare a reference to a global queue, 164a247c996SSascha Wildnerand to define the implementation of the queue. 165a247c996SSascha WildnerThe 166a247c996SSascha Wildner.Fn TASKQUEUE_DEFINE 167a247c996SSascha Wildnermacro arranges to call 168a247c996SSascha Wildner.Fn taskqueue_create 169a247c996SSascha Wildnerwith the values of its 170a247c996SSascha Wildner.Fa name , 171a247c996SSascha Wildner.Fa enqueue 172a247c996SSascha Wildnerand 173a247c996SSascha Wildner.Fa context 174a247c996SSascha Wildnerarguments during system initialisation. 175a247c996SSascha WildnerAfter calling 176a247c996SSascha Wildner.Fn taskqueue_create , 177a247c996SSascha Wildnerthe 178a247c996SSascha Wildner.Fa init 179a247c996SSascha Wildnerargument to the macro is executed as a C statement, 180a247c996SSascha Wildnerallowing any further initialisation to be performed 181a247c996SSascha Wildner(such as registering an interrupt handler etc.) 182a247c996SSascha Wildner.Pp 183a247c996SSascha WildnerThe system provides a global taskqueue, 184a247c996SSascha Wildner.Va taskqueue_swi , 185a247c996SSascha Wildnerwhich is run via a software interrupt mechanism. 186a247c996SSascha WildnerTo use this queue, call 187a247c996SSascha Wildner.Fn taskqueue_enqueue 188a247c996SSascha Wildnerwith the value of the global variable 189a247c996SSascha Wildner.Va taskqueue_swi . 190a247c996SSascha Wildner.Pp 191a247c996SSascha WildnerThis queue can be used, 192a247c996SSascha Wildnerfor instance, for implementing interrupt handlers which must perform a 193a247c996SSascha Wildnersignificant amount of processing in the handler. 194a247c996SSascha WildnerThe hardware interrupt handler would perform minimal processing of the 195a247c996SSascha Wildnerinterrupt and then enqueue a task to finish the work. 196a247c996SSascha WildnerThis reduces to a minimum 197a247c996SSascha Wildnerthe amount of time spent with interrupts disabled. 198a247c996SSascha Wildner.\".Sh SEE ALSO 199a247c996SSascha Wildner.\".Xr ithread 9 , 200a247c996SSascha Wildner.\".Xr kthread 9 , 201a247c996SSascha Wildner.\".Xr swi 9 202a247c996SSascha Wildner.Sh HISTORY 203a247c996SSascha WildnerThis interface first appeared in 204a247c996SSascha Wildner.Fx 5.0 . 205a247c996SSascha WildnerThere is a similar facility called tqueue in the Linux kernel. 206a247c996SSascha Wildner.Sh AUTHORS 207a247c996SSascha WildnerThis manual page was written by 208a247c996SSascha Wildner.An Doug Rabson . 209