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*337f6465SAndriy Gapon.Dd October 17, 2019 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 72*337f6465SAndriy Gapon.Fo taskqueue_start_threads_cpuset 73*337f6465SAndriy Gapon.Fa "struct taskqueue **tqp" "int count" "int pri" "cpuset_t *mask" 74*337f6465SAndriy Gapon.Fa "const char *name" "..." 75*337f6465SAndriy Gapon.Fc 76*337f6465SAndriy Gapon.Ft int 77*337f6465SAndriy Gapon.Fo taskqueue_start_threads_in_proc 78*337f6465SAndriy Gapon.Fa "struct taskqueue **tqp" "int count" "int pri" "struct proc *proc" 79ec5d37f4SBenjamin Kaduk.Fa "const char *name" "..." 80ec5d37f4SBenjamin Kaduk.Fc 81fdbc7174SWill Andrews.Ft void 82fdbc7174SWill Andrews.Fn taskqueue_set_callback "struct taskqueue *queue" "enum taskqueue_callback_type cb_type" "taskqueue_callback_fn callback" "void *context" 8382323455SDoug Rabson.Ft void 8482323455SDoug Rabson.Fn taskqueue_free "struct taskqueue *queue" 8582323455SDoug Rabson.Ft int 8682323455SDoug Rabson.Fn taskqueue_enqueue "struct taskqueue *queue" "struct task *task" 8724b4e9d1SScott Long.Ft int 88c3bd10b4SKonstantin Belousov.Fn taskqueue_enqueue_timeout "struct taskqueue *queue" "struct timeout_task *timeout_task" "int ticks" 89c3bd10b4SKonstantin Belousov.Ft int 90f37b7fc2SIan Lepore.Fn taskqueue_enqueue_timeout_sbt "struct taskqueue *queue" "struct timeout_task *timeout_task" "sbintime_t sbt" "sbintime_t pr" "int flags" 91f37b7fc2SIan Lepore.Ft int 92f46276a9SMatthew D Fleming.Fn taskqueue_cancel "struct taskqueue *queue" "struct task *task" "u_int *pendp" 93c3bd10b4SKonstantin Belousov.Ft int 94c3bd10b4SKonstantin Belousov.Fn taskqueue_cancel_timeout "struct taskqueue *queue" "struct timeout_task *timeout_task" "u_int *pendp" 9582323455SDoug Rabson.Ft void 96fff7ff71SGleb Smirnoff.Fn taskqueue_drain "struct taskqueue *queue" "struct task *task" 97c3bd10b4SKonstantin Belousov.Ft void 98c3bd10b4SKonstantin Belousov.Fn taskqueue_drain_timeout "struct taskqueue *queue" "struct timeout_task *timeout_task" 99cb03508fSAndriy Gapon.Ft void 100cb03508fSAndriy Gapon.Fn taskqueue_drain_all "struct taskqueue *queue" 101cb03508fSAndriy Gapon.Ft void 102bb58b5d6SMark Johnston.Fn taskqueue_quiesce "struct taskqueue *queue" 103bb58b5d6SMark Johnston.Ft void 104cb03508fSAndriy Gapon.Fn taskqueue_block "struct taskqueue *queue" 105cb03508fSAndriy Gapon.Ft void 106cb03508fSAndriy Gapon.Fn taskqueue_unblock "struct taskqueue *queue" 107159ef108SPawel Jakub Dawidek.Ft int 108159ef108SPawel Jakub Dawidek.Fn taskqueue_member "struct taskqueue *queue" "struct thread *td" 109a92f0ee8SMatthew D Fleming.Ft void 110bf73d4d2SMatthew D Fleming.Fn taskqueue_run "struct taskqueue *queue" 111c3bd10b4SKonstantin Belousov.Fn TASK_INIT "struct task *task" "int priority" "task_fn_t func" "void *context" 112a7f5f794SJohn Baldwin.Fn TASK_INITIALIZER "int priority" "task_fn_t func" "void *context" 11382323455SDoug Rabson.Fn TASKQUEUE_DECLARE "name" 114f16b3c0dSChad David.Fn TASKQUEUE_DEFINE "name" "taskqueue_enqueue_fn enqueue" "void *context" "init" 1152eb30874SOleksandr Tymoshenko.Fn TASKQUEUE_FAST_DEFINE "name" "taskqueue_enqueue_fn enqueue" "void *context" "init" 116227559d1SJohn-Mark Gurney.Fn TASKQUEUE_DEFINE_THREAD "name" 1172eb30874SOleksandr Tymoshenko.Fn TASKQUEUE_FAST_DEFINE_THREAD "name" 118c3bd10b4SKonstantin Belousov.Fn TIMEOUT_TASK_INIT "struct taskqueue *queue" "struct timeout_task *timeout_task" "int priority" "task_fn_t func" "void *context" 11982323455SDoug Rabson.Sh DESCRIPTION 12082323455SDoug RabsonThese functions provide a simple interface for asynchronous execution 12182323455SDoug Rabsonof code. 12282323455SDoug Rabson.Pp 12382323455SDoug RabsonThe function 12482323455SDoug Rabson.Fn taskqueue_create 12582323455SDoug Rabsonis used to create new queues. 12682323455SDoug RabsonThe arguments to 12782323455SDoug Rabson.Fn taskqueue_create 128cf82599dSSam Lefflerinclude a name that should be unique, 12982323455SDoug Rabsona set of 13082323455SDoug Rabson.Xr malloc 9 131cf82599dSSam Lefflerflags that specify whether the call to 13282323455SDoug Rabson.Fn malloc 133cf82599dSSam Leffleris allowed to sleep, 134cf82599dSSam Lefflera function that is called from 13582323455SDoug Rabson.Fn taskqueue_enqueue 136cf82599dSSam Lefflerwhen a task is added to the queue, 137cf82599dSSam Lefflerand a pointer to the memory location where the identity of the 138cf82599dSSam Lefflerthread that services the queue is recorded. 13982323455SDoug Rabson.\" XXX The rest of the sentence gets lots in relation to the first part. 140cf82599dSSam LefflerThe function called from 141cf82599dSSam Leffler.Fn taskqueue_enqueue 142cf82599dSSam Lefflermust arrange for the queue to be processed 14382323455SDoug Rabson(for instance by scheduling a software interrupt or waking a kernel 14482323455SDoug Rabsonthread). 145cf82599dSSam LefflerThe memory location where the thread identity is recorded is used 146cf82599dSSam Lefflerto signal the service thread(s) to terminate--when this value is set to 147cf82599dSSam Lefflerzero and the thread is signaled it will terminate. 1482eb30874SOleksandr TymoshenkoIf the queue is intended for use in fast interrupt handlers 1492eb30874SOleksandr Tymoshenko.Fn taskqueue_create_fast 1502eb30874SOleksandr Tymoshenkoshould be used in place of 1512eb30874SOleksandr Tymoshenko.Fn taskqueue_create . 15282323455SDoug Rabson.Pp 15382323455SDoug RabsonThe function 15482323455SDoug Rabson.Fn taskqueue_free 155e477e4feSPawel Jakub Dawidekshould be used to free the memory used by the queue. 156cf82599dSSam LefflerAny tasks that are on the queue will be executed at this time after 157cf82599dSSam Lefflerwhich the thread servicing the queue will be signaled that it should exit. 15882323455SDoug Rabson.Pp 159fdbc7174SWill AndrewsOnce a taskqueue has been created, its threads should be started using 160*337f6465SAndriy Gapon.Fn taskqueue_start_threads , 161*337f6465SAndriy Gapon.Fn taskqueue_start_threads_cpuset 162ec5d37f4SBenjamin Kadukor 163*337f6465SAndriy Gapon.Fn taskqueue_start_threads_in_proc . 164*337f6465SAndriy Gapon.Fn taskqueue_start_threads_cpuset 165ec5d37f4SBenjamin Kaduktakes a 166*337f6465SAndriy Gapon.Va cpuset 167ec5d37f4SBenjamin Kadukargument which will cause the threads which are started for the taskqueue 168*337f6465SAndriy Gaponto be restricted to run on the given CPUs. 169*337f6465SAndriy Gapon.Fn taskqueue_start_threads_in_proc 170*337f6465SAndriy Gapontakes a 171*337f6465SAndriy Gapon.Va proc 172*337f6465SAndriy Gaponargument which will cause the threads which are started for the taskqueue 173*337f6465SAndriy Gaponto be assigned to the given kernel process. 174fdbc7174SWill AndrewsCallbacks may optionally be registered using 175fdbc7174SWill Andrews.Fn taskqueue_set_callback . 176fdbc7174SWill AndrewsCurrently, callbacks may be registered for the following purposes: 177fdbc7174SWill Andrews.Bl -tag -width TASKQUEUE_CALLBACK_TYPE_SHUTDOWN 178fdbc7174SWill Andrews.It Dv TASKQUEUE_CALLBACK_TYPE_INIT 179fdbc7174SWill AndrewsThis callback is called by every thread in the taskqueue, before it executes 180fdbc7174SWill Andrewsany tasks. 181fdbc7174SWill AndrewsThis callback must be set before the taskqueue's threads are started. 182fdbc7174SWill Andrews.It Dv TASKQUEUE_CALLBACK_TYPE_SHUTDOWN 183fdbc7174SWill AndrewsThis callback is called by every thread in the taskqueue, after it executes 184fdbc7174SWill Andrewsits last task. 185fdbc7174SWill AndrewsThis callback will always be called before the taskqueue structure is 186fdbc7174SWill Andrewsreclaimed. 187fdbc7174SWill Andrews.El 188fdbc7174SWill Andrews.Pp 18982323455SDoug RabsonTo add a task to the list of tasks queued on a taskqueue, call 19082323455SDoug Rabson.Fn taskqueue_enqueue 19182323455SDoug Rabsonwith pointers to the queue and task. 19282323455SDoug RabsonIf the task's 19382323455SDoug Rabson.Va ta_pending 19482323455SDoug Rabsonfield is non-zero, 19582323455SDoug Rabsonthen it is simply incremented to reflect the number of times the task 196d2849f27SAdrian Chaddwas enqueued, up to a cap of USHRT_MAX. 19782323455SDoug RabsonOtherwise, 19882323455SDoug Rabsonthe task is added to the list before the first task which has a lower 19982323455SDoug Rabson.Va ta_priority 20082323455SDoug Rabsonvalue or at the end of the list if no tasks have a lower priority. 20182323455SDoug RabsonEnqueueing a task does not perform any memory allocation which makes 20282323455SDoug Rabsonit suitable for calling from an interrupt handler. 20382323455SDoug RabsonThis function will return 204b92a189eSRuslan Ermilov.Er EPIPE 20582323455SDoug Rabsonif the queue is being freed. 20682323455SDoug Rabson.Pp 20782323455SDoug RabsonWhen a task is executed, 20882323455SDoug Rabsonfirst it is removed from the queue, 20982323455SDoug Rabsonthe value of 21082323455SDoug Rabson.Va ta_pending 21182323455SDoug Rabsonis recorded and then the field is zeroed. 21282323455SDoug RabsonThe function 21382323455SDoug Rabson.Va ta_func 21482323455SDoug Rabsonfrom the task structure is called with the value of the field 21582323455SDoug Rabson.Va ta_context 21682323455SDoug Rabsonas its first argument 21782323455SDoug Rabsonand the value of 21882323455SDoug Rabson.Va ta_pending 21982323455SDoug Rabsonas its second argument. 220f616cf33SJohn-Mark GurneyAfter the function 221f616cf33SJohn-Mark Gurney.Va ta_func 222f616cf33SJohn-Mark Gurneyreturns, 223f616cf33SJohn-Mark Gurney.Xr wakeup 9 224f616cf33SJohn-Mark Gurneyis called on the task pointer passed to 225f616cf33SJohn-Mark Gurney.Fn taskqueue_enqueue . 22682323455SDoug Rabson.Pp 227fff7ff71SGleb SmirnoffThe 228c3bd10b4SKonstantin Belousov.Fn taskqueue_enqueue_timeout 229f37b7fc2SIan Leporefunction is used to schedule the enqueue after the specified number of 230c3bd10b4SKonstantin Belousov.Va ticks . 231f37b7fc2SIan LeporeThe 232f37b7fc2SIan Lepore.Fn taskqueue_enqueue_timeout_sbt 233f37b7fc2SIan Leporefunction provides finer control over the scheduling based on 234f37b7fc2SIan Lepore.Va sbt , 235f37b7fc2SIan Lepore.Va pr , 236f37b7fc2SIan Leporeand 237f37b7fc2SIan Lepore.Va flags , 238f37b7fc2SIan Leporeas detailed in 239f37b7fc2SIan Lepore.Xr timeout 9 . 240c3bd10b4SKonstantin BelousovOnly non-fast task queues can be used for 241c3bd10b4SKonstantin Belousov.Va timeout_task 242c3bd10b4SKonstantin Belousovscheduling. 243471af3a8SKonstantin BelousovIf the 244471af3a8SKonstantin Belousov.Va ticks 245471af3a8SKonstantin Belousovargument is negative, the already scheduled enqueueing is not re-scheduled. 246c1e231bcSKonstantin BelousovOtherwise, the task is scheduled for enqueueing in the future, 247471af3a8SKonstantin Belousovafter the absolute value of 248471af3a8SKonstantin Belousov.Va ticks 249471af3a8SKonstantin Belousovis passed. 2506a3536aaSHans Petter SelaskyThis function returns -1 if the task is being drained. 2516a3536aaSHans Petter SelaskyOtherwise, the number of pending calls is returned. 252c3bd10b4SKonstantin Belousov.Pp 253c3bd10b4SKonstantin BelousovThe 254f46276a9SMatthew D Fleming.Fn taskqueue_cancel 255f46276a9SMatthew D Flemingfunction is used to cancel a task. 256f46276a9SMatthew D FlemingThe 257f46276a9SMatthew D Fleming.Va ta_pending 258f46276a9SMatthew D Flemingcount is cleared, and the old value returned in the reference 259f46276a9SMatthew D Flemingparameter 260f46276a9SMatthew D Fleming.Fa pendp , 26173bbeaa5SGlen Barberif it is 26273bbeaa5SGlen Barber.Pf non- Dv NULL . 263f46276a9SMatthew D FlemingIf the task is currently running, 264f46276a9SMatthew D Fleming.Dv EBUSY 265f46276a9SMatthew D Flemingis returned, otherwise 0. 266f46276a9SMatthew D FlemingTo implement a blocking 267f46276a9SMatthew D Fleming.Fn taskqueue_cancel 268f46276a9SMatthew D Flemingthat waits for a running task to finish, it could look like: 269f46276a9SMatthew D Fleming.Bd -literal -offset indent 270f46276a9SMatthew D Flemingwhile (taskqueue_cancel(tq, task, NULL) != 0) 271f46276a9SMatthew D Fleming taskqueue_drain(tq, task); 272f46276a9SMatthew D Fleming.Ed 273f46276a9SMatthew D Fleming.Pp 274f46276a9SMatthew D FlemingNote that, as with 275f46276a9SMatthew D Fleming.Fn taskqueue_drain , 276f46276a9SMatthew D Flemingthe caller is responsible for ensuring that the task is not re-enqueued 277f46276a9SMatthew D Flemingafter being canceled. 278f46276a9SMatthew D Fleming.Pp 279c3bd10b4SKonstantin BelousovSimilarly, the 280c3bd10b4SKonstantin Belousov.Fn taskqueue_cancel_timeout 281c3bd10b4SKonstantin Belousovfunction is used to cancel the scheduled task execution. 282c3bd10b4SKonstantin Belousov.Pp 283f46276a9SMatthew D FlemingThe 284fff7ff71SGleb Smirnoff.Fn taskqueue_drain 285c3bd10b4SKonstantin Belousovfunction is used to wait for the task to finish, and 286c3bd10b4SKonstantin Belousovthe 287c3bd10b4SKonstantin Belousov.Fn taskqueue_drain_timeout 288c3bd10b4SKonstantin Belousovfunction is used to wait for the scheduled task to finish. 289fff7ff71SGleb SmirnoffThere is no guarantee that the task will not be 290fff7ff71SGleb Smirnoffenqueued after call to 291fff7ff71SGleb Smirnoff.Fn taskqueue_drain . 292cb03508fSAndriy GaponIf the caller wants to put the task into a known state, 293cb03508fSAndriy Gaponthen before calling 294cb03508fSAndriy Gapon.Fn taskqueue_drain 295cb03508fSAndriy Gaponthe caller should use out-of-band means to ensure that the task 296cb03508fSAndriy Gaponwould not be enqueued. 297cb03508fSAndriy GaponFor example, if the task is enqueued by an interrupt filter, then 298cb03508fSAndriy Gaponthe interrupt could be disabled. 299cb03508fSAndriy Gapon.Pp 300cb03508fSAndriy GaponThe 301cb03508fSAndriy Gapon.Fn taskqueue_drain_all 302cb03508fSAndriy Gaponfunction is used to wait for all pending and running tasks that 303cb03508fSAndriy Gaponare enqueued on the taskqueue to finish. 3045b326a32SJustin T. GibbsTasks posted to the taskqueue after 305cb03508fSAndriy Gapon.Fn taskqueue_drain_all 3065b326a32SJustin T. Gibbsbegins processing, 3075b326a32SJustin T. Gibbsincluding pending enqueues scheduled by a previous call to 3085b326a32SJustin T. Gibbs.Fn taskqueue_enqueue_timeout , 3095b326a32SJustin T. Gibbsdo not extend the wait time of 3105b326a32SJustin T. Gibbs.Fn taskqueue_drain_all 3115b326a32SJustin T. Gibbsand may complete after 3125b326a32SJustin T. Gibbs.Fn taskqueue_drain_all 3135b326a32SJustin T. Gibbsreturns. 314bb58b5d6SMark JohnstonThe 315bb58b5d6SMark Johnston.Fn taskqueue_quiesce 316bb58b5d6SMark Johnstonfunction is used to wait for the queue to become empty and for all 317bb58b5d6SMark Johnstonrunning tasks to finish. 318bb58b5d6SMark JohnstonTo avoid blocking indefinitely, the caller must ensure by some mechanism 319bb58b5d6SMark Johnstonthat tasks will eventually stop being posted to the queue. 320cb03508fSAndriy Gapon.Pp 321cb03508fSAndriy GaponThe 322cb03508fSAndriy Gapon.Fn taskqueue_block 323cb03508fSAndriy Gaponfunction blocks the taskqueue. 324cb03508fSAndriy GaponIt prevents any enqueued but not running tasks from being executed. 325cb03508fSAndriy GaponFuture calls to 326cb03508fSAndriy Gapon.Fn taskqueue_enqueue 327cb03508fSAndriy Gaponwill enqueue tasks, but the tasks will not be run until 328cb03508fSAndriy Gapon.Fn taskqueue_unblock 329cb03508fSAndriy Gaponis called. 330cb03508fSAndriy GaponPlease note that 331cb03508fSAndriy Gapon.Fn taskqueue_block 332cb03508fSAndriy Gapondoes not wait for any currently running tasks to finish. 333cb03508fSAndriy GaponThus, the 334cb03508fSAndriy Gapon.Fn taskqueue_block 335cb03508fSAndriy Gapondoes not provide a guarantee that 336cb03508fSAndriy Gapon.Fn taskqueue_run 337cb03508fSAndriy Gaponis not running after 338cb03508fSAndriy Gapon.Fn taskqueue_block 339cb03508fSAndriy Gaponreturns, but it does provide a guarantee that 340cb03508fSAndriy Gapon.Fn taskqueue_run 341cb03508fSAndriy Gaponwill not be called again 342cb03508fSAndriy Gaponuntil 343cb03508fSAndriy Gapon.Fn taskqueue_unblock 344cb03508fSAndriy Gaponis called. 345cb03508fSAndriy GaponIf the caller requires a guarantee that 346cb03508fSAndriy Gapon.Fn taskqueue_run 347cb03508fSAndriy Gaponis not running, then this must be arranged by the caller. 348cb03508fSAndriy GaponNote that if 349cb03508fSAndriy Gapon.Fn taskqueue_drain 350cb03508fSAndriy Gaponis called on a task that is enqueued on a taskqueue that is blocked by 351cb03508fSAndriy Gapon.Fn taskqueue_block , 352cb03508fSAndriy Gaponthen 353cb03508fSAndriy Gapon.Fn taskqueue_drain 354cb03508fSAndriy Gaponcan not return until the taskqueue is unblocked. 355cb03508fSAndriy GaponThis can result in a deadlock if the thread blocked in 356cb03508fSAndriy Gapon.Fn taskqueue_drain 357cb03508fSAndriy Gaponis the thread that is supposed to call 358cb03508fSAndriy Gapon.Fn taskqueue_unblock . 359cb03508fSAndriy GaponThus, use of 360cb03508fSAndriy Gapon.Fn taskqueue_drain 361cb03508fSAndriy Gaponafter 362cb03508fSAndriy Gapon.Fn taskqueue_block 363cb03508fSAndriy Gaponis discouraged, because the state of the task can not be known in advance. 364cb03508fSAndriy GaponThe same caveat applies to 365cb03508fSAndriy Gapon.Fn taskqueue_drain_all . 366cb03508fSAndriy Gapon.Pp 367cb03508fSAndriy GaponThe 368cb03508fSAndriy Gapon.Fn taskqueue_unblock 369cb03508fSAndriy Gaponfunction unblocks the previously blocked taskqueue. 370cb03508fSAndriy GaponAll enqueued tasks can be run after this call. 371fff7ff71SGleb Smirnoff.Pp 372159ef108SPawel Jakub DawidekThe 373159ef108SPawel Jakub Dawidek.Fn taskqueue_member 374159ef108SPawel Jakub Dawidekfunction returns 375159ef108SPawel Jakub Dawidek.No 1 3769c1a8ce4SPawel Jakub Dawidekif the given thread 377159ef108SPawel Jakub Dawidek.Fa td 3789ba47352SJoel Dahlis part of the given taskqueue 379159ef108SPawel Jakub Dawidek.Fa queue 380159ef108SPawel Jakub Dawidekand 381159ef108SPawel Jakub Dawidek.No 0 382159ef108SPawel Jakub Dawidekotherwise. 383159ef108SPawel Jakub Dawidek.Pp 384a92f0ee8SMatthew D FlemingThe 385a92f0ee8SMatthew D Fleming.Fn taskqueue_run 386a92f0ee8SMatthew D Flemingfunction will run all pending tasks in the specified 387a92f0ee8SMatthew D Fleming.Fa queue . 388a92f0ee8SMatthew D FlemingNormally this function is only used internally. 389a92f0ee8SMatthew D Fleming.Pp 39082323455SDoug RabsonA convenience macro, 39182323455SDoug Rabson.Fn TASK_INIT "task" "priority" "func" "context" 39282323455SDoug Rabsonis provided to initialise a 39382323455SDoug Rabson.Va task 39482323455SDoug Rabsonstructure. 395a7f5f794SJohn BaldwinThe 396a7f5f794SJohn Baldwin.Fn TASK_INITIALIZER 397a7f5f794SJohn Baldwinmacro generates an initializer for a task structure. 398c3bd10b4SKonstantin BelousovA macro 399c3bd10b4SKonstantin Belousov.Fn TIMEOUT_TASK_INIT "queue" "timeout_task" "priority" "func" "context" 400a7f5f794SJohn Baldwininitializes the 401a7f5f794SJohn Baldwin.Va timeout_task 402a7f5f794SJohn Baldwinstructure. 40382323455SDoug RabsonThe values of 40482323455SDoug Rabson.Va priority , 40582323455SDoug Rabson.Va func , 40682323455SDoug Rabsonand 40782323455SDoug Rabson.Va context 40882323455SDoug Rabsonare simply copied into the task structure fields and the 40982323455SDoug Rabson.Va ta_pending 41082323455SDoug Rabsonfield is cleared. 41182323455SDoug Rabson.Pp 4122eb30874SOleksandr TymoshenkoFive macros 413227559d1SJohn-Mark Gurney.Fn TASKQUEUE_DECLARE "name" , 414227559d1SJohn-Mark Gurney.Fn TASKQUEUE_DEFINE "name" "enqueue" "context" "init" , 4152eb30874SOleksandr Tymoshenko.Fn TASKQUEUE_FAST_DEFINE "name" "enqueue" "context" "init" , 41682323455SDoug Rabsonand 417227559d1SJohn-Mark Gurney.Fn TASKQUEUE_DEFINE_THREAD "name" 4182eb30874SOleksandr Tymoshenko.Fn TASKQUEUE_FAST_DEFINE_THREAD "name" 419227559d1SJohn-Mark Gurneyare used to declare a reference to a global queue, to define the 420c0854fb7SRuslan Ermilovimplementation of the queue, and declare a queue that uses its own thread. 42182323455SDoug RabsonThe 42282323455SDoug Rabson.Fn TASKQUEUE_DEFINE 42382323455SDoug Rabsonmacro arranges to call 42482323455SDoug Rabson.Fn taskqueue_create 42582323455SDoug Rabsonwith the values of its 42682323455SDoug Rabson.Va name , 42782323455SDoug Rabson.Va enqueue 42882323455SDoug Rabsonand 42982323455SDoug Rabson.Va context 43082323455SDoug Rabsonarguments during system initialisation. 43182323455SDoug RabsonAfter calling 43282323455SDoug Rabson.Fn taskqueue_create , 43382323455SDoug Rabsonthe 43482323455SDoug Rabson.Va init 43582323455SDoug Rabsonargument to the macro is executed as a C statement, 43682323455SDoug Rabsonallowing any further initialisation to be performed 4372e17a50fSBenjamin Kaduk(such as registering an interrupt handler, etc.). 43882323455SDoug Rabson.Pp 439227559d1SJohn-Mark GurneyThe 440227559d1SJohn-Mark Gurney.Fn TASKQUEUE_DEFINE_THREAD 441c0854fb7SRuslan Ermilovmacro defines a new taskqueue with its own kernel thread to serve tasks. 442c0854fb7SRuslan ErmilovThe variable 443227559d1SJohn-Mark Gurney.Vt struct taskqueue *taskqueue_name 444227559d1SJohn-Mark Gurneyis used to enqueue tasks onto the queue. 4452eb30874SOleksandr Tymoshenko.Pp 4462eb30874SOleksandr Tymoshenko.Fn TASKQUEUE_FAST_DEFINE 4472eb30874SOleksandr Tymoshenkoand 4482eb30874SOleksandr Tymoshenko.Fn TASKQUEUE_FAST_DEFINE_THREAD 4492eb30874SOleksandr Tymoshenkoact just like 4502eb30874SOleksandr Tymoshenko.Fn TASKQUEUE_DEFINE 4512eb30874SOleksandr Tymoshenkoand 4522eb30874SOleksandr Tymoshenko.Fn TASKQUEUE_DEFINE_THREAD 4532eb30874SOleksandr Tymoshenkorespectively but taskqueue is created with 4542eb30874SOleksandr Tymoshenko.Fn taskqueue_create_fast . 4554c49b002SJoseph Koshy.Ss Predefined Task Queues 4564c49b002SJoseph KoshyThe system provides four global taskqueues, 4574c49b002SJoseph Koshy.Va taskqueue_fast , 45882323455SDoug Rabson.Va taskqueue_swi , 459cb32189eSKenneth D. Merry.Va taskqueue_swi_giant , 460cb32189eSKenneth D. Merryand 461cb32189eSKenneth D. Merry.Va taskqueue_thread . 4624c49b002SJoseph KoshyThe 4634c49b002SJoseph Koshy.Va taskqueue_fast 4644c49b002SJoseph Koshyqueue is for swi handlers dispatched from fast interrupt handlers, 4654c49b002SJoseph Koshywhere sleep mutexes cannot be used. 466cb32189eSKenneth D. MerryThe swi taskqueues are run via a software interrupt mechanism. 4674c49b002SJoseph KoshyThe 4684c49b002SJoseph Koshy.Va taskqueue_swi 4694c49b002SJoseph Koshyqueue runs without the protection of the 4704c49b002SJoseph Koshy.Va Giant 4714c49b002SJoseph Koshykernel lock, and the 4724c49b002SJoseph Koshy.Va taskqueue_swi_giant 4734c49b002SJoseph Koshyqueue runs with the protection of the 4744c49b002SJoseph Koshy.Va Giant 475cb32189eSKenneth D. Merrykernel lock. 4764c49b002SJoseph KoshyThe thread taskqueue 4774c49b002SJoseph Koshy.Va taskqueue_thread 4784c49b002SJoseph Koshyruns in a kernel thread context, and tasks run from this thread do 4794c49b002SJoseph Koshynot run under the 4804c49b002SJoseph Koshy.Va Giant 4814c49b002SJoseph Koshykernel lock. 4824c49b002SJoseph KoshyIf the caller wants to run under 4834c49b002SJoseph Koshy.Va Giant , 4844c49b002SJoseph Koshyhe should explicitly acquire and release 4854c49b002SJoseph Koshy.Va Giant 4864c49b002SJoseph Koshyin his taskqueue handler routine. 487bf7f20c2SRuslan Ermilov.Pp 488cb32189eSKenneth D. MerryTo use these queues, 48982323455SDoug Rabsoncall 49082323455SDoug Rabson.Fn taskqueue_enqueue 491cb32189eSKenneth D. Merrywith the value of the global taskqueue variable for the queue you wish to 492cbc4d2dbSJohn Baldwinuse. 49382323455SDoug Rabson.Pp 494e0254f10SKenneth D. MerryThe software interrupt queues can be used, 49582323455SDoug Rabsonfor instance, for implementing interrupt handlers which must perform a 49682323455SDoug Rabsonsignificant amount of processing in the handler. 49782323455SDoug RabsonThe hardware interrupt handler would perform minimal processing of the 49882323455SDoug Rabsoninterrupt and then enqueue a task to finish the work. 49982323455SDoug RabsonThis reduces to a minimum 50082323455SDoug Rabsonthe amount of time spent with interrupts disabled. 501cb32189eSKenneth D. Merry.Pp 502cb32189eSKenneth D. MerryThe thread queue can be used, for instance, by interrupt level routines 503cb32189eSKenneth D. Merrythat need to call kernel functions that do things that can only be done 504cb32189eSKenneth D. Merryfrom a thread context. 505cb32189eSKenneth D. Merry(e.g., call malloc with the M_WAITOK flag.) 506cf82599dSSam Leffler.Pp 507cf82599dSSam LefflerNote that tasks queued on shared taskqueues such as 508cf82599dSSam Leffler.Va taskqueue_swi 509cf82599dSSam Lefflermay be delayed an indeterminate amount of time before execution. 510cf82599dSSam LefflerIf queueing delays cannot be tolerated then a private taskqueue should 511cf82599dSSam Lefflerbe created with a dedicated processing thread. 5123bbf58f9SJoseph Koshy.Sh SEE ALSO 5133bbf58f9SJoseph Koshy.Xr ithread 9 , 5143bbf58f9SJoseph Koshy.Xr kthread 9 , 5153bbf58f9SJoseph Koshy.Xr swi 9 516f37b7fc2SIan Lepore.Xr timeout 9 51782323455SDoug Rabson.Sh HISTORY 51882323455SDoug RabsonThis interface first appeared in 51982323455SDoug Rabson.Fx 5.0 . 520c3bd10b4SKonstantin BelousovThere is a similar facility called work_queue in the Linux kernel. 52182323455SDoug Rabson.Sh AUTHORS 522571dba6eSHiten PandyaThis manual page was written by 52382323455SDoug Rabson.An Doug Rabson . 524