182323455SDoug Rabson.\" -*- nroff -*- 282323455SDoug Rabson.\" 382323455SDoug Rabson.\" Copyright (c) 2000 Doug Rabson 482323455SDoug Rabson.\" 582323455SDoug Rabson.\" All rights reserved. 682323455SDoug Rabson.\" 782323455SDoug Rabson.\" This program is free software. 882323455SDoug Rabson.\" 982323455SDoug Rabson.\" Redistribution and use in source and binary forms, with or without 1082323455SDoug Rabson.\" modification, are permitted provided that the following conditions 1182323455SDoug Rabson.\" are met: 1282323455SDoug Rabson.\" 1. Redistributions of source code must retain the above copyright 1382323455SDoug Rabson.\" notice, this list of conditions and the following disclaimer. 1482323455SDoug Rabson.\" 2. Redistributions in binary form must reproduce the above copyright 1582323455SDoug Rabson.\" notice, this list of conditions and the following disclaimer in the 1682323455SDoug Rabson.\" documentation and/or other materials provided with the distribution. 1782323455SDoug Rabson.\" 1882323455SDoug Rabson.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR 1982323455SDoug Rabson.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2082323455SDoug Rabson.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2182323455SDoug Rabson.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT, 2282323455SDoug Rabson.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2382323455SDoug Rabson.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2482323455SDoug Rabson.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2582323455SDoug Rabson.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2682323455SDoug Rabson.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2782323455SDoug Rabson.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2882323455SDoug Rabson.\" 2982323455SDoug Rabson.\" $FreeBSD$ 3082323455SDoug Rabson.\" 31*cbc4d2dbSJohn Baldwin.Dd March 1, 2016 3282323455SDoug Rabson.Dt TASKQUEUE 9 3382323455SDoug Rabson.Os 3482323455SDoug Rabson.Sh NAME 3582323455SDoug Rabson.Nm taskqueue 3682323455SDoug Rabson.Nd asynchronous task execution 3782323455SDoug Rabson.Sh SYNOPSIS 3832eef9aeSRuslan Ermilov.In sys/param.h 39f16b3c0dSChad David.In sys/kernel.h 40f16b3c0dSChad David.In sys/malloc.h 4132eef9aeSRuslan Ermilov.In sys/queue.h 4232eef9aeSRuslan Ermilov.In sys/taskqueue.h 4382323455SDoug Rabson.Bd -literal 44f674e945SBruce M Simpsontypedef void (*task_fn_t)(void *context, int pending); 4582323455SDoug Rabson 4682323455SDoug Rabsontypedef void (*taskqueue_enqueue_fn)(void *context); 4782323455SDoug Rabson 4882323455SDoug Rabsonstruct task { 4982323455SDoug Rabson STAILQ_ENTRY(task) ta_link; /* link for queue */ 50cf82599dSSam Leffler u_short ta_pending; /* count times queued */ 51cf82599dSSam Leffler u_short ta_priority; /* priority of task in queue */ 52f674e945SBruce M Simpson task_fn_t ta_func; /* task handler */ 5382323455SDoug Rabson void *ta_context; /* argument for handler */ 5482323455SDoug Rabson}; 55c3bd10b4SKonstantin Belousov 56fdbc7174SWill Andrewsenum taskqueue_callback_type { 57fdbc7174SWill Andrews TASKQUEUE_CALLBACK_TYPE_INIT, 58fdbc7174SWill Andrews TASKQUEUE_CALLBACK_TYPE_SHUTDOWN, 59fdbc7174SWill Andrews}; 60fdbc7174SWill Andrews 61fdbc7174SWill Andrewstypedef void (*taskqueue_callback_fn)(void *context); 62fdbc7174SWill Andrews 63c3bd10b4SKonstantin Belousovstruct timeout_task; 6482323455SDoug Rabson.Ed 6582323455SDoug Rabson.Ft struct taskqueue * 668f668ffaSOleksandr Tymoshenko.Fn taskqueue_create "const char *name" "int mflags" "taskqueue_enqueue_fn enqueue" "void *context" 672eb30874SOleksandr Tymoshenko.Ft struct taskqueue * 682eb30874SOleksandr Tymoshenko.Fn taskqueue_create_fast "const char *name" "int mflags" "taskqueue_enqueue_fn enqueue" "void *context" 69fdbc7174SWill Andrews.Ft int 70fdbc7174SWill Andrews.Fn taskqueue_start_threads "struct taskqueue **tqp" "int count" "int pri" "const char *name" "..." 71ec5d37f4SBenjamin Kaduk.Ft int 72ec5d37f4SBenjamin Kaduk.Fo taskqueue_start_threads_pinned 73ec5d37f4SBenjamin Kaduk.Fa "struct taskqueue **tqp" "int count" "int pri" "int cpu_id" 74ec5d37f4SBenjamin Kaduk.Fa "const char *name" "..." 75ec5d37f4SBenjamin Kaduk.Fc 76fdbc7174SWill Andrews.Ft void 77fdbc7174SWill Andrews.Fn taskqueue_set_callback "struct taskqueue *queue" "enum taskqueue_callback_type cb_type" "taskqueue_callback_fn callback" "void *context" 7882323455SDoug Rabson.Ft void 7982323455SDoug Rabson.Fn taskqueue_free "struct taskqueue *queue" 8082323455SDoug Rabson.Ft int 8182323455SDoug Rabson.Fn taskqueue_enqueue "struct taskqueue *queue" "struct task *task" 8224b4e9d1SScott Long.Ft int 83c3bd10b4SKonstantin Belousov.Fn taskqueue_enqueue_timeout "struct taskqueue *queue" "struct timeout_task *timeout_task" "int ticks" 84c3bd10b4SKonstantin Belousov.Ft int 85f46276a9SMatthew D Fleming.Fn taskqueue_cancel "struct taskqueue *queue" "struct task *task" "u_int *pendp" 86c3bd10b4SKonstantin Belousov.Ft int 87c3bd10b4SKonstantin Belousov.Fn taskqueue_cancel_timeout "struct taskqueue *queue" "struct timeout_task *timeout_task" "u_int *pendp" 8882323455SDoug Rabson.Ft void 89fff7ff71SGleb Smirnoff.Fn taskqueue_drain "struct taskqueue *queue" "struct task *task" 90c3bd10b4SKonstantin Belousov.Ft void 91c3bd10b4SKonstantin Belousov.Fn taskqueue_drain_timeout "struct taskqueue *queue" "struct timeout_task *timeout_task" 92cb03508fSAndriy Gapon.Ft void 93cb03508fSAndriy Gapon.Fn taskqueue_drain_all "struct taskqueue *queue" 94cb03508fSAndriy Gapon.Ft void 95cb03508fSAndriy Gapon.Fn taskqueue_block "struct taskqueue *queue" 96cb03508fSAndriy Gapon.Ft void 97cb03508fSAndriy Gapon.Fn taskqueue_unblock "struct taskqueue *queue" 98159ef108SPawel Jakub Dawidek.Ft int 99159ef108SPawel Jakub Dawidek.Fn taskqueue_member "struct taskqueue *queue" "struct thread *td" 100a92f0ee8SMatthew D Fleming.Ft void 101bf73d4d2SMatthew D Fleming.Fn taskqueue_run "struct taskqueue *queue" 102c3bd10b4SKonstantin Belousov.Fn TASK_INIT "struct task *task" "int priority" "task_fn_t func" "void *context" 103a7f5f794SJohn Baldwin.Fn TASK_INITIALIZER "int priority" "task_fn_t func" "void *context" 10482323455SDoug Rabson.Fn TASKQUEUE_DECLARE "name" 105f16b3c0dSChad David.Fn TASKQUEUE_DEFINE "name" "taskqueue_enqueue_fn enqueue" "void *context" "init" 1062eb30874SOleksandr Tymoshenko.Fn TASKQUEUE_FAST_DEFINE "name" "taskqueue_enqueue_fn enqueue" "void *context" "init" 107227559d1SJohn-Mark Gurney.Fn TASKQUEUE_DEFINE_THREAD "name" 1082eb30874SOleksandr Tymoshenko.Fn TASKQUEUE_FAST_DEFINE_THREAD "name" 109c3bd10b4SKonstantin Belousov.Fn TIMEOUT_TASK_INIT "struct taskqueue *queue" "struct timeout_task *timeout_task" "int priority" "task_fn_t func" "void *context" 11082323455SDoug Rabson.Sh DESCRIPTION 11182323455SDoug RabsonThese functions provide a simple interface for asynchronous execution 11282323455SDoug Rabsonof code. 11382323455SDoug Rabson.Pp 11482323455SDoug RabsonThe function 11582323455SDoug Rabson.Fn taskqueue_create 11682323455SDoug Rabsonis used to create new queues. 11782323455SDoug RabsonThe arguments to 11882323455SDoug Rabson.Fn taskqueue_create 119cf82599dSSam Lefflerinclude a name that should be unique, 12082323455SDoug Rabsona set of 12182323455SDoug Rabson.Xr malloc 9 122cf82599dSSam Lefflerflags that specify whether the call to 12382323455SDoug Rabson.Fn malloc 124cf82599dSSam Leffleris allowed to sleep, 125cf82599dSSam Lefflera function that is called from 12682323455SDoug Rabson.Fn taskqueue_enqueue 127cf82599dSSam Lefflerwhen a task is added to the queue, 128cf82599dSSam Lefflerand a pointer to the memory location where the identity of the 129cf82599dSSam Lefflerthread that services the queue is recorded. 13082323455SDoug Rabson.\" XXX The rest of the sentence gets lots in relation to the first part. 131cf82599dSSam LefflerThe function called from 132cf82599dSSam Leffler.Fn taskqueue_enqueue 133cf82599dSSam Lefflermust arrange for the queue to be processed 13482323455SDoug Rabson(for instance by scheduling a software interrupt or waking a kernel 13582323455SDoug Rabsonthread). 136cf82599dSSam LefflerThe memory location where the thread identity is recorded is used 137cf82599dSSam Lefflerto signal the service thread(s) to terminate--when this value is set to 138cf82599dSSam Lefflerzero and the thread is signaled it will terminate. 1392eb30874SOleksandr TymoshenkoIf the queue is intended for use in fast interrupt handlers 1402eb30874SOleksandr Tymoshenko.Fn taskqueue_create_fast 1412eb30874SOleksandr Tymoshenkoshould be used in place of 1422eb30874SOleksandr Tymoshenko.Fn taskqueue_create . 14382323455SDoug Rabson.Pp 14482323455SDoug RabsonThe function 14582323455SDoug Rabson.Fn taskqueue_free 146e477e4feSPawel Jakub Dawidekshould be used to free the memory used by the queue. 147cf82599dSSam LefflerAny tasks that are on the queue will be executed at this time after 148cf82599dSSam Lefflerwhich the thread servicing the queue will be signaled that it should exit. 14982323455SDoug Rabson.Pp 150fdbc7174SWill AndrewsOnce a taskqueue has been created, its threads should be started using 151ec5d37f4SBenjamin Kaduk.Fn taskqueue_start_threads 152ec5d37f4SBenjamin Kadukor 153ec5d37f4SBenjamin Kaduk.Fn taskqueue_start_threads_pinned . 154ec5d37f4SBenjamin Kaduk.Fn taskqueue_start_threads_pinned 155ec5d37f4SBenjamin Kaduktakes a 156ec5d37f4SBenjamin Kaduk.Va cpu_id 157ec5d37f4SBenjamin Kadukargument which will cause the threads which are started for the taskqueue 158ec5d37f4SBenjamin Kadukto be pinned to run on the given CPU. 159fdbc7174SWill AndrewsCallbacks may optionally be registered using 160fdbc7174SWill Andrews.Fn taskqueue_set_callback . 161fdbc7174SWill AndrewsCurrently, callbacks may be registered for the following purposes: 162fdbc7174SWill Andrews.Bl -tag -width TASKQUEUE_CALLBACK_TYPE_SHUTDOWN 163fdbc7174SWill Andrews.It Dv TASKQUEUE_CALLBACK_TYPE_INIT 164fdbc7174SWill AndrewsThis callback is called by every thread in the taskqueue, before it executes 165fdbc7174SWill Andrewsany tasks. 166fdbc7174SWill AndrewsThis callback must be set before the taskqueue's threads are started. 167fdbc7174SWill Andrews.It Dv TASKQUEUE_CALLBACK_TYPE_SHUTDOWN 168fdbc7174SWill AndrewsThis callback is called by every thread in the taskqueue, after it executes 169fdbc7174SWill Andrewsits last task. 170fdbc7174SWill AndrewsThis callback will always be called before the taskqueue structure is 171fdbc7174SWill Andrewsreclaimed. 172fdbc7174SWill Andrews.El 173fdbc7174SWill Andrews.Pp 17482323455SDoug RabsonTo add a task to the list of tasks queued on a taskqueue, call 17582323455SDoug Rabson.Fn taskqueue_enqueue 17682323455SDoug Rabsonwith pointers to the queue and task. 17782323455SDoug RabsonIf the task's 17882323455SDoug Rabson.Va ta_pending 17982323455SDoug Rabsonfield is non-zero, 18082323455SDoug Rabsonthen it is simply incremented to reflect the number of times the task 181d2849f27SAdrian Chaddwas enqueued, up to a cap of USHRT_MAX. 18282323455SDoug RabsonOtherwise, 18382323455SDoug Rabsonthe task is added to the list before the first task which has a lower 18482323455SDoug Rabson.Va ta_priority 18582323455SDoug Rabsonvalue or at the end of the list if no tasks have a lower priority. 18682323455SDoug RabsonEnqueueing a task does not perform any memory allocation which makes 18782323455SDoug Rabsonit suitable for calling from an interrupt handler. 18882323455SDoug RabsonThis function will return 189b92a189eSRuslan Ermilov.Er EPIPE 19082323455SDoug Rabsonif the queue is being freed. 19182323455SDoug Rabson.Pp 19282323455SDoug RabsonWhen a task is executed, 19382323455SDoug Rabsonfirst it is removed from the queue, 19482323455SDoug Rabsonthe value of 19582323455SDoug Rabson.Va ta_pending 19682323455SDoug Rabsonis recorded and then the field is zeroed. 19782323455SDoug RabsonThe function 19882323455SDoug Rabson.Va ta_func 19982323455SDoug Rabsonfrom the task structure is called with the value of the field 20082323455SDoug Rabson.Va ta_context 20182323455SDoug Rabsonas its first argument 20282323455SDoug Rabsonand the value of 20382323455SDoug Rabson.Va ta_pending 20482323455SDoug Rabsonas its second argument. 205f616cf33SJohn-Mark GurneyAfter the function 206f616cf33SJohn-Mark Gurney.Va ta_func 207f616cf33SJohn-Mark Gurneyreturns, 208f616cf33SJohn-Mark Gurney.Xr wakeup 9 209f616cf33SJohn-Mark Gurneyis called on the task pointer passed to 210f616cf33SJohn-Mark Gurney.Fn taskqueue_enqueue . 21182323455SDoug Rabson.Pp 212fff7ff71SGleb SmirnoffThe 213c3bd10b4SKonstantin Belousov.Fn taskqueue_enqueue_timeout 214c3bd10b4SKonstantin Belousovis used to schedule the enqueue after the specified amount of 215c3bd10b4SKonstantin Belousov.Va ticks . 216c3bd10b4SKonstantin BelousovOnly non-fast task queues can be used for 217c3bd10b4SKonstantin Belousov.Va timeout_task 218c3bd10b4SKonstantin Belousovscheduling. 219471af3a8SKonstantin BelousovIf the 220471af3a8SKonstantin Belousov.Va ticks 221471af3a8SKonstantin Belousovargument is negative, the already scheduled enqueueing is not re-scheduled. 222c1e231bcSKonstantin BelousovOtherwise, the task is scheduled for enqueueing in the future, 223471af3a8SKonstantin Belousovafter the absolute value of 224471af3a8SKonstantin Belousov.Va ticks 225471af3a8SKonstantin Belousovis passed. 226c3bd10b4SKonstantin Belousov.Pp 227c3bd10b4SKonstantin BelousovThe 228f46276a9SMatthew D Fleming.Fn taskqueue_cancel 229f46276a9SMatthew D Flemingfunction is used to cancel a task. 230f46276a9SMatthew D FlemingThe 231f46276a9SMatthew D Fleming.Va ta_pending 232f46276a9SMatthew D Flemingcount is cleared, and the old value returned in the reference 233f46276a9SMatthew D Flemingparameter 234f46276a9SMatthew D Fleming.Fa pendp , 23573bbeaa5SGlen Barberif it is 23673bbeaa5SGlen Barber.Pf non- Dv NULL . 237f46276a9SMatthew D FlemingIf the task is currently running, 238f46276a9SMatthew D Fleming.Dv EBUSY 239f46276a9SMatthew D Flemingis returned, otherwise 0. 240f46276a9SMatthew D FlemingTo implement a blocking 241f46276a9SMatthew D Fleming.Fn taskqueue_cancel 242f46276a9SMatthew D Flemingthat waits for a running task to finish, it could look like: 243f46276a9SMatthew D Fleming.Bd -literal -offset indent 244f46276a9SMatthew D Flemingwhile (taskqueue_cancel(tq, task, NULL) != 0) 245f46276a9SMatthew D Fleming taskqueue_drain(tq, task); 246f46276a9SMatthew D Fleming.Ed 247f46276a9SMatthew D Fleming.Pp 248f46276a9SMatthew D FlemingNote that, as with 249f46276a9SMatthew D Fleming.Fn taskqueue_drain , 250f46276a9SMatthew D Flemingthe caller is responsible for ensuring that the task is not re-enqueued 251f46276a9SMatthew D Flemingafter being canceled. 252f46276a9SMatthew D Fleming.Pp 253c3bd10b4SKonstantin BelousovSimilarly, the 254c3bd10b4SKonstantin Belousov.Fn taskqueue_cancel_timeout 255c3bd10b4SKonstantin Belousovfunction is used to cancel the scheduled task execution. 256c3bd10b4SKonstantin Belousov.Pp 257f46276a9SMatthew D FlemingThe 258fff7ff71SGleb Smirnoff.Fn taskqueue_drain 259c3bd10b4SKonstantin Belousovfunction is used to wait for the task to finish, and 260c3bd10b4SKonstantin Belousovthe 261c3bd10b4SKonstantin Belousov.Fn taskqueue_drain_timeout 262c3bd10b4SKonstantin Belousovfunction is used to wait for the scheduled task to finish. 263fff7ff71SGleb SmirnoffThere is no guarantee that the task will not be 264fff7ff71SGleb Smirnoffenqueued after call to 265fff7ff71SGleb Smirnoff.Fn taskqueue_drain . 266cb03508fSAndriy GaponIf the caller wants to put the task into a known state, 267cb03508fSAndriy Gaponthen before calling 268cb03508fSAndriy Gapon.Fn taskqueue_drain 269cb03508fSAndriy Gaponthe caller should use out-of-band means to ensure that the task 270cb03508fSAndriy Gaponwould not be enqueued. 271cb03508fSAndriy GaponFor example, if the task is enqueued by an interrupt filter, then 272cb03508fSAndriy Gaponthe interrupt could be disabled. 273cb03508fSAndriy Gapon.Pp 274cb03508fSAndriy GaponThe 275cb03508fSAndriy Gapon.Fn taskqueue_drain_all 276cb03508fSAndriy Gaponfunction is used to wait for all pending and running tasks that 277cb03508fSAndriy Gaponare enqueued on the taskqueue to finish. 2785b326a32SJustin T. GibbsTasks posted to the taskqueue after 279cb03508fSAndriy Gapon.Fn taskqueue_drain_all 2805b326a32SJustin T. Gibbsbegins processing, 2815b326a32SJustin T. Gibbsincluding pending enqueues scheduled by a previous call to 2825b326a32SJustin T. Gibbs.Fn taskqueue_enqueue_timeout , 2835b326a32SJustin T. Gibbsdo not extend the wait time of 2845b326a32SJustin T. Gibbs.Fn taskqueue_drain_all 2855b326a32SJustin T. Gibbsand may complete after 2865b326a32SJustin T. Gibbs.Fn taskqueue_drain_all 2875b326a32SJustin T. Gibbsreturns. 288cb03508fSAndriy Gapon.Pp 289cb03508fSAndriy GaponThe 290cb03508fSAndriy Gapon.Fn taskqueue_block 291cb03508fSAndriy Gaponfunction blocks the taskqueue. 292cb03508fSAndriy GaponIt prevents any enqueued but not running tasks from being executed. 293cb03508fSAndriy GaponFuture calls to 294cb03508fSAndriy Gapon.Fn taskqueue_enqueue 295cb03508fSAndriy Gaponwill enqueue tasks, but the tasks will not be run until 296cb03508fSAndriy Gapon.Fn taskqueue_unblock 297cb03508fSAndriy Gaponis called. 298cb03508fSAndriy GaponPlease note that 299cb03508fSAndriy Gapon.Fn taskqueue_block 300cb03508fSAndriy Gapondoes not wait for any currently running tasks to finish. 301cb03508fSAndriy GaponThus, the 302cb03508fSAndriy Gapon.Fn taskqueue_block 303cb03508fSAndriy Gapondoes not provide a guarantee that 304cb03508fSAndriy Gapon.Fn taskqueue_run 305cb03508fSAndriy Gaponis not running after 306cb03508fSAndriy Gapon.Fn taskqueue_block 307cb03508fSAndriy Gaponreturns, but it does provide a guarantee that 308cb03508fSAndriy Gapon.Fn taskqueue_run 309cb03508fSAndriy Gaponwill not be called again 310cb03508fSAndriy Gaponuntil 311cb03508fSAndriy Gapon.Fn taskqueue_unblock 312cb03508fSAndriy Gaponis called. 313cb03508fSAndriy GaponIf the caller requires a guarantee that 314cb03508fSAndriy Gapon.Fn taskqueue_run 315cb03508fSAndriy Gaponis not running, then this must be arranged by the caller. 316cb03508fSAndriy GaponNote that if 317cb03508fSAndriy Gapon.Fn taskqueue_drain 318cb03508fSAndriy Gaponis called on a task that is enqueued on a taskqueue that is blocked by 319cb03508fSAndriy Gapon.Fn taskqueue_block , 320cb03508fSAndriy Gaponthen 321cb03508fSAndriy Gapon.Fn taskqueue_drain 322cb03508fSAndriy Gaponcan not return until the taskqueue is unblocked. 323cb03508fSAndriy GaponThis can result in a deadlock if the thread blocked in 324cb03508fSAndriy Gapon.Fn taskqueue_drain 325cb03508fSAndriy Gaponis the thread that is supposed to call 326cb03508fSAndriy Gapon.Fn taskqueue_unblock . 327cb03508fSAndriy GaponThus, use of 328cb03508fSAndriy Gapon.Fn taskqueue_drain 329cb03508fSAndriy Gaponafter 330cb03508fSAndriy Gapon.Fn taskqueue_block 331cb03508fSAndriy Gaponis discouraged, because the state of the task can not be known in advance. 332cb03508fSAndriy GaponThe same caveat applies to 333cb03508fSAndriy Gapon.Fn taskqueue_drain_all . 334cb03508fSAndriy Gapon.Pp 335cb03508fSAndriy GaponThe 336cb03508fSAndriy Gapon.Fn taskqueue_unblock 337cb03508fSAndriy Gaponfunction unblocks the previously blocked taskqueue. 338cb03508fSAndriy GaponAll enqueued tasks can be run after this call. 339fff7ff71SGleb Smirnoff.Pp 340159ef108SPawel Jakub DawidekThe 341159ef108SPawel Jakub Dawidek.Fn taskqueue_member 342159ef108SPawel Jakub Dawidekfunction returns 343159ef108SPawel Jakub Dawidek.No 1 3449c1a8ce4SPawel Jakub Dawidekif the given thread 345159ef108SPawel Jakub Dawidek.Fa td 3469ba47352SJoel Dahlis part of the given taskqueue 347159ef108SPawel Jakub Dawidek.Fa queue 348159ef108SPawel Jakub Dawidekand 349159ef108SPawel Jakub Dawidek.No 0 350159ef108SPawel Jakub Dawidekotherwise. 351159ef108SPawel Jakub Dawidek.Pp 352a92f0ee8SMatthew D FlemingThe 353a92f0ee8SMatthew D Fleming.Fn taskqueue_run 354a92f0ee8SMatthew D Flemingfunction will run all pending tasks in the specified 355a92f0ee8SMatthew D Fleming.Fa queue . 356a92f0ee8SMatthew D FlemingNormally this function is only used internally. 357a92f0ee8SMatthew D Fleming.Pp 35882323455SDoug RabsonA convenience macro, 35982323455SDoug Rabson.Fn TASK_INIT "task" "priority" "func" "context" 36082323455SDoug Rabsonis provided to initialise a 36182323455SDoug Rabson.Va task 36282323455SDoug Rabsonstructure. 363a7f5f794SJohn BaldwinThe 364a7f5f794SJohn Baldwin.Fn TASK_INITIALIZER 365a7f5f794SJohn Baldwinmacro generates an initializer for a task structure. 366c3bd10b4SKonstantin BelousovA macro 367c3bd10b4SKonstantin Belousov.Fn TIMEOUT_TASK_INIT "queue" "timeout_task" "priority" "func" "context" 368a7f5f794SJohn Baldwininitializes the 369a7f5f794SJohn Baldwin.Va timeout_task 370a7f5f794SJohn Baldwinstructure. 37182323455SDoug RabsonThe values of 37282323455SDoug Rabson.Va priority , 37382323455SDoug Rabson.Va func , 37482323455SDoug Rabsonand 37582323455SDoug Rabson.Va context 37682323455SDoug Rabsonare simply copied into the task structure fields and the 37782323455SDoug Rabson.Va ta_pending 37882323455SDoug Rabsonfield is cleared. 37982323455SDoug Rabson.Pp 3802eb30874SOleksandr TymoshenkoFive macros 381227559d1SJohn-Mark Gurney.Fn TASKQUEUE_DECLARE "name" , 382227559d1SJohn-Mark Gurney.Fn TASKQUEUE_DEFINE "name" "enqueue" "context" "init" , 3832eb30874SOleksandr Tymoshenko.Fn TASKQUEUE_FAST_DEFINE "name" "enqueue" "context" "init" , 38482323455SDoug Rabsonand 385227559d1SJohn-Mark Gurney.Fn TASKQUEUE_DEFINE_THREAD "name" 3862eb30874SOleksandr Tymoshenko.Fn TASKQUEUE_FAST_DEFINE_THREAD "name" 387227559d1SJohn-Mark Gurneyare used to declare a reference to a global queue, to define the 388c0854fb7SRuslan Ermilovimplementation of the queue, and declare a queue that uses its own thread. 38982323455SDoug RabsonThe 39082323455SDoug Rabson.Fn TASKQUEUE_DEFINE 39182323455SDoug Rabsonmacro arranges to call 39282323455SDoug Rabson.Fn taskqueue_create 39382323455SDoug Rabsonwith the values of its 39482323455SDoug Rabson.Va name , 39582323455SDoug Rabson.Va enqueue 39682323455SDoug Rabsonand 39782323455SDoug Rabson.Va context 39882323455SDoug Rabsonarguments during system initialisation. 39982323455SDoug RabsonAfter calling 40082323455SDoug Rabson.Fn taskqueue_create , 40182323455SDoug Rabsonthe 40282323455SDoug Rabson.Va init 40382323455SDoug Rabsonargument to the macro is executed as a C statement, 40482323455SDoug Rabsonallowing any further initialisation to be performed 40582323455SDoug Rabson(such as registering an interrupt handler etc.) 40682323455SDoug Rabson.Pp 407227559d1SJohn-Mark GurneyThe 408227559d1SJohn-Mark Gurney.Fn TASKQUEUE_DEFINE_THREAD 409c0854fb7SRuslan Ermilovmacro defines a new taskqueue with its own kernel thread to serve tasks. 410c0854fb7SRuslan ErmilovThe variable 411227559d1SJohn-Mark Gurney.Vt struct taskqueue *taskqueue_name 412227559d1SJohn-Mark Gurneyis used to enqueue tasks onto the queue. 4132eb30874SOleksandr Tymoshenko.Pp 4142eb30874SOleksandr Tymoshenko.Fn TASKQUEUE_FAST_DEFINE 4152eb30874SOleksandr Tymoshenkoand 4162eb30874SOleksandr Tymoshenko.Fn TASKQUEUE_FAST_DEFINE_THREAD 4172eb30874SOleksandr Tymoshenkoact just like 4182eb30874SOleksandr Tymoshenko.Fn TASKQUEUE_DEFINE 4192eb30874SOleksandr Tymoshenkoand 4202eb30874SOleksandr Tymoshenko.Fn TASKQUEUE_DEFINE_THREAD 4212eb30874SOleksandr Tymoshenkorespectively but taskqueue is created with 4222eb30874SOleksandr Tymoshenko.Fn taskqueue_create_fast . 4234c49b002SJoseph Koshy.Ss Predefined Task Queues 4244c49b002SJoseph KoshyThe system provides four global taskqueues, 4254c49b002SJoseph Koshy.Va taskqueue_fast , 42682323455SDoug Rabson.Va taskqueue_swi , 427cb32189eSKenneth D. Merry.Va taskqueue_swi_giant , 428cb32189eSKenneth D. Merryand 429cb32189eSKenneth D. Merry.Va taskqueue_thread . 4304c49b002SJoseph KoshyThe 4314c49b002SJoseph Koshy.Va taskqueue_fast 4324c49b002SJoseph Koshyqueue is for swi handlers dispatched from fast interrupt handlers, 4334c49b002SJoseph Koshywhere sleep mutexes cannot be used. 434cb32189eSKenneth D. MerryThe swi taskqueues are run via a software interrupt mechanism. 4354c49b002SJoseph KoshyThe 4364c49b002SJoseph Koshy.Va taskqueue_swi 4374c49b002SJoseph Koshyqueue runs without the protection of the 4384c49b002SJoseph Koshy.Va Giant 4394c49b002SJoseph Koshykernel lock, and the 4404c49b002SJoseph Koshy.Va taskqueue_swi_giant 4414c49b002SJoseph Koshyqueue runs with the protection of the 4424c49b002SJoseph Koshy.Va Giant 443cb32189eSKenneth D. Merrykernel lock. 4444c49b002SJoseph KoshyThe thread taskqueue 4454c49b002SJoseph Koshy.Va taskqueue_thread 4464c49b002SJoseph Koshyruns in a kernel thread context, and tasks run from this thread do 4474c49b002SJoseph Koshynot run under the 4484c49b002SJoseph Koshy.Va Giant 4494c49b002SJoseph Koshykernel lock. 4504c49b002SJoseph KoshyIf the caller wants to run under 4514c49b002SJoseph Koshy.Va Giant , 4524c49b002SJoseph Koshyhe should explicitly acquire and release 4534c49b002SJoseph Koshy.Va Giant 4544c49b002SJoseph Koshyin his taskqueue handler routine. 455bf7f20c2SRuslan Ermilov.Pp 456cb32189eSKenneth D. MerryTo use these queues, 45782323455SDoug Rabsoncall 45882323455SDoug Rabson.Fn taskqueue_enqueue 459cb32189eSKenneth D. Merrywith the value of the global taskqueue variable for the queue you wish to 460*cbc4d2dbSJohn Baldwinuse. 46182323455SDoug Rabson.Pp 462e0254f10SKenneth D. MerryThe software interrupt queues can be used, 46382323455SDoug Rabsonfor instance, for implementing interrupt handlers which must perform a 46482323455SDoug Rabsonsignificant amount of processing in the handler. 46582323455SDoug RabsonThe hardware interrupt handler would perform minimal processing of the 46682323455SDoug Rabsoninterrupt and then enqueue a task to finish the work. 46782323455SDoug RabsonThis reduces to a minimum 46882323455SDoug Rabsonthe amount of time spent with interrupts disabled. 469cb32189eSKenneth D. Merry.Pp 470cb32189eSKenneth D. MerryThe thread queue can be used, for instance, by interrupt level routines 471cb32189eSKenneth D. Merrythat need to call kernel functions that do things that can only be done 472cb32189eSKenneth D. Merryfrom a thread context. 473cb32189eSKenneth D. Merry(e.g., call malloc with the M_WAITOK flag.) 474cf82599dSSam Leffler.Pp 475cf82599dSSam LefflerNote that tasks queued on shared taskqueues such as 476cf82599dSSam Leffler.Va taskqueue_swi 477cf82599dSSam Lefflermay be delayed an indeterminate amount of time before execution. 478cf82599dSSam LefflerIf queueing delays cannot be tolerated then a private taskqueue should 479cf82599dSSam Lefflerbe created with a dedicated processing thread. 4803bbf58f9SJoseph Koshy.Sh SEE ALSO 4813bbf58f9SJoseph Koshy.Xr ithread 9 , 4823bbf58f9SJoseph Koshy.Xr kthread 9 , 4833bbf58f9SJoseph Koshy.Xr swi 9 48482323455SDoug Rabson.Sh HISTORY 48582323455SDoug RabsonThis interface first appeared in 48682323455SDoug Rabson.Fx 5.0 . 487c3bd10b4SKonstantin BelousovThere is a similar facility called work_queue in the Linux kernel. 48882323455SDoug Rabson.Sh AUTHORS 489571dba6eSHiten PandyaThis manual page was written by 49082323455SDoug Rabson.An Doug Rabson . 491