/share/man/man9/taskqueue.9

https://bitbucket.org/freebsd/freebsd-head/ · Unknown · 382 lines · 379 code · 3 blank · 0 comment · 0 complexity · 45ac376fa7c09c41978bee07a78187da MD5 · raw file

  1. .\" -*- nroff -*-
  2. .\"
  3. .\" Copyright (c) 2000 Doug Rabson
  4. .\"
  5. .\" All rights reserved.
  6. .\"
  7. .\" This program is free software.
  8. .\"
  9. .\" Redistribution and use in source and binary forms, with or without
  10. .\" modification, are permitted provided that the following conditions
  11. .\" are met:
  12. .\" 1. Redistributions of source code must retain the above copyright
  13. .\" notice, this list of conditions and the following disclaimer.
  14. .\" 2. Redistributions in binary form must reproduce the above copyright
  15. .\" notice, this list of conditions and the following disclaimer in the
  16. .\" documentation and/or other materials provided with the distribution.
  17. .\"
  18. .\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
  19. .\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  20. .\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  21. .\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
  22. .\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  23. .\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  24. .\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  25. .\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  26. .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  27. .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28. .\"
  29. .\" $FreeBSD$
  30. .\"
  31. .Dd April 26, 2011
  32. .Dt TASKQUEUE 9
  33. .Os
  34. .Sh NAME
  35. .Nm taskqueue
  36. .Nd asynchronous task execution
  37. .Sh SYNOPSIS
  38. .In sys/param.h
  39. .In sys/kernel.h
  40. .In sys/malloc.h
  41. .In sys/queue.h
  42. .In sys/taskqueue.h
  43. .Bd -literal
  44. typedef void (*task_fn_t)(void *context, int pending);
  45. typedef void (*taskqueue_enqueue_fn)(void *context);
  46. struct task {
  47. STAILQ_ENTRY(task) ta_link; /* link for queue */
  48. u_short ta_pending; /* count times queued */
  49. u_short ta_priority; /* priority of task in queue */
  50. task_fn_t ta_func; /* task handler */
  51. void *ta_context; /* argument for handler */
  52. };
  53. struct timeout_task;
  54. .Ed
  55. .Ft struct taskqueue *
  56. .Fn taskqueue_create "const char *name" "int mflags" "taskqueue_enqueue_fn enqueue" "void *context"
  57. .Ft struct taskqueue *
  58. .Fn taskqueue_create_fast "const char *name" "int mflags" "taskqueue_enqueue_fn enqueue" "void *context"
  59. .Ft void
  60. .Fn taskqueue_free "struct taskqueue *queue"
  61. .Ft int
  62. .Fn taskqueue_enqueue "struct taskqueue *queue" "struct task *task"
  63. .Ft int
  64. .Fn taskqueue_enqueue_fast "struct taskqueue *queue" "struct task *task"
  65. .Ft int
  66. .Fn taskqueue_enqueue_timeout "struct taskqueue *queue" "struct timeout_task *timeout_task" "int ticks"
  67. .Ft int
  68. .Fn taskqueue_cancel "struct taskqueue *queue" "struct task *task" "u_int *pendp"
  69. .Ft int
  70. .Fn taskqueue_cancel_timeout "struct taskqueue *queue" "struct timeout_task *timeout_task" "u_int *pendp"
  71. .Ft void
  72. .Fn taskqueue_drain "struct taskqueue *queue" "struct task *task"
  73. .Ft void
  74. .Fn taskqueue_drain_timeout "struct taskqueue *queue" "struct timeout_task *timeout_task"
  75. .Ft int
  76. .Fn taskqueue_member "struct taskqueue *queue" "struct thread *td"
  77. .Ft void
  78. .Fn taskqueue_run "struct taskqueue *queue"
  79. .Fn TASK_INIT "struct task *task" "int priority" "task_fn_t func" "void *context"
  80. .Fn TASK_INITIALIZER "int priority" "task_fn_t func" "void *context"
  81. .Fn TASKQUEUE_DECLARE "name"
  82. .Fn TASKQUEUE_DEFINE "name" "taskqueue_enqueue_fn enqueue" "void *context" "init"
  83. .Fn TASKQUEUE_FAST_DEFINE "name" "taskqueue_enqueue_fn enqueue" "void *context" "init"
  84. .Fn TASKQUEUE_DEFINE_THREAD "name"
  85. .Fn TASKQUEUE_FAST_DEFINE_THREAD "name"
  86. .Fn TIMEOUT_TASK_INIT "struct taskqueue *queue" "struct timeout_task *timeout_task" "int priority" "task_fn_t func" "void *context"
  87. .Sh DESCRIPTION
  88. These functions provide a simple interface for asynchronous execution
  89. of code.
  90. .Pp
  91. The function
  92. .Fn taskqueue_create
  93. is used to create new queues.
  94. The arguments to
  95. .Fn taskqueue_create
  96. include a name that should be unique,
  97. a set of
  98. .Xr malloc 9
  99. flags that specify whether the call to
  100. .Fn malloc
  101. is allowed to sleep,
  102. a function that is called from
  103. .Fn taskqueue_enqueue
  104. when a task is added to the queue,
  105. and a pointer to the memory location where the identity of the
  106. thread that services the queue is recorded.
  107. .\" XXX The rest of the sentence gets lots in relation to the first part.
  108. The function called from
  109. .Fn taskqueue_enqueue
  110. must arrange for the queue to be processed
  111. (for instance by scheduling a software interrupt or waking a kernel
  112. thread).
  113. The memory location where the thread identity is recorded is used
  114. to signal the service thread(s) to terminate--when this value is set to
  115. zero and the thread is signaled it will terminate.
  116. If the queue is intended for use in fast interrupt handlers
  117. .Fn taskqueue_create_fast
  118. should be used in place of
  119. .Fn taskqueue_create .
  120. .Pp
  121. The function
  122. .Fn taskqueue_free
  123. should be used to free the memory used by the queue.
  124. Any tasks that are on the queue will be executed at this time after
  125. which the thread servicing the queue will be signaled that it should exit.
  126. .Pp
  127. To add a task to the list of tasks queued on a taskqueue, call
  128. .Fn taskqueue_enqueue
  129. with pointers to the queue and task.
  130. If the task's
  131. .Va ta_pending
  132. field is non-zero,
  133. then it is simply incremented to reflect the number of times the task
  134. was enqueued, up to a cap of USHRT_MAX.
  135. Otherwise,
  136. the task is added to the list before the first task which has a lower
  137. .Va ta_priority
  138. value or at the end of the list if no tasks have a lower priority.
  139. Enqueueing a task does not perform any memory allocation which makes
  140. it suitable for calling from an interrupt handler.
  141. This function will return
  142. .Er EPIPE
  143. if the queue is being freed.
  144. .Pp
  145. The function
  146. .Fn taskqueue_enqueue_fast
  147. should be used in place of
  148. .Fn taskqueue_enqueue
  149. when the enqueuing must happen from a fast interrupt handler.
  150. This method uses spin locks to avoid the possibility of sleeping in the fast
  151. interrupt context.
  152. .Pp
  153. When a task is executed,
  154. first it is removed from the queue,
  155. the value of
  156. .Va ta_pending
  157. is recorded and then the field is zeroed.
  158. The function
  159. .Va ta_func
  160. from the task structure is called with the value of the field
  161. .Va ta_context
  162. as its first argument
  163. and the value of
  164. .Va ta_pending
  165. as its second argument.
  166. After the function
  167. .Va ta_func
  168. returns,
  169. .Xr wakeup 9
  170. is called on the task pointer passed to
  171. .Fn taskqueue_enqueue .
  172. .Pp
  173. The
  174. .Fn taskqueue_enqueue_timeout
  175. is used to schedule the enqueue after the specified amount of
  176. .Va ticks .
  177. Only non-fast task queues can be used for
  178. .Va timeout_task
  179. scheduling.
  180. .Pp
  181. The
  182. .Fn taskqueue_cancel
  183. function is used to cancel a task.
  184. The
  185. .Va ta_pending
  186. count is cleared, and the old value returned in the reference
  187. parameter
  188. .Fa pendp ,
  189. if it is
  190. .Pf non- Dv NULL .
  191. If the task is currently running,
  192. .Dv EBUSY
  193. is returned, otherwise 0.
  194. To implement a blocking
  195. .Fn taskqueue_cancel
  196. that waits for a running task to finish, it could look like:
  197. .Bd -literal -offset indent
  198. while (taskqueue_cancel(tq, task, NULL) != 0)
  199. taskqueue_drain(tq, task);
  200. .Ed
  201. .Pp
  202. Note that, as with
  203. .Fn taskqueue_drain ,
  204. the caller is responsible for ensuring that the task is not re-enqueued
  205. after being canceled.
  206. .Pp
  207. Similarly, the
  208. .Fn taskqueue_cancel_timeout
  209. function is used to cancel the scheduled task execution.
  210. .Pp
  211. The
  212. .Fn taskqueue_drain
  213. function is used to wait for the task to finish, and
  214. the
  215. .Fn taskqueue_drain_timeout
  216. function is used to wait for the scheduled task to finish.
  217. There is no guarantee that the task will not be
  218. enqueued after call to
  219. .Fn taskqueue_drain .
  220. .Pp
  221. The
  222. .Fn taskqueue_member
  223. function returns
  224. .No 1
  225. if the given thread
  226. .Fa td
  227. is part of the given taskqueue
  228. .Fa queue
  229. and
  230. .No 0
  231. otherwise.
  232. .Pp
  233. The
  234. .Fn taskqueue_run
  235. function will run all pending tasks in the specified
  236. .Fa queue .
  237. Normally this function is only used internally.
  238. .Pp
  239. A convenience macro,
  240. .Fn TASK_INIT "task" "priority" "func" "context"
  241. is provided to initialise a
  242. .Va task
  243. structure.
  244. The
  245. .Fn TASK_INITIALIZER
  246. macro generates an initializer for a task structure.
  247. A macro
  248. .Fn TIMEOUT_TASK_INIT "queue" "timeout_task" "priority" "func" "context"
  249. initializes the
  250. .Va timeout_task
  251. structure.
  252. The values of
  253. .Va priority ,
  254. .Va func ,
  255. and
  256. .Va context
  257. are simply copied into the task structure fields and the
  258. .Va ta_pending
  259. field is cleared.
  260. .Pp
  261. Five macros
  262. .Fn TASKQUEUE_DECLARE "name" ,
  263. .Fn TASKQUEUE_DEFINE "name" "enqueue" "context" "init" ,
  264. .Fn TASKQUEUE_FAST_DEFINE "name" "enqueue" "context" "init" ,
  265. and
  266. .Fn TASKQUEUE_DEFINE_THREAD "name"
  267. .Fn TASKQUEUE_FAST_DEFINE_THREAD "name"
  268. are used to declare a reference to a global queue, to define the
  269. implementation of the queue, and declare a queue that uses its own thread.
  270. The
  271. .Fn TASKQUEUE_DEFINE
  272. macro arranges to call
  273. .Fn taskqueue_create
  274. with the values of its
  275. .Va name ,
  276. .Va enqueue
  277. and
  278. .Va context
  279. arguments during system initialisation.
  280. After calling
  281. .Fn taskqueue_create ,
  282. the
  283. .Va init
  284. argument to the macro is executed as a C statement,
  285. allowing any further initialisation to be performed
  286. (such as registering an interrupt handler etc.)
  287. .Pp
  288. The
  289. .Fn TASKQUEUE_DEFINE_THREAD
  290. macro defines a new taskqueue with its own kernel thread to serve tasks.
  291. The variable
  292. .Vt struct taskqueue *taskqueue_name
  293. is used to enqueue tasks onto the queue.
  294. .Pp
  295. .Fn TASKQUEUE_FAST_DEFINE
  296. and
  297. .Fn TASKQUEUE_FAST_DEFINE_THREAD
  298. act just like
  299. .Fn TASKQUEUE_DEFINE
  300. and
  301. .Fn TASKQUEUE_DEFINE_THREAD
  302. respectively but taskqueue is created with
  303. .Fn taskqueue_create_fast .
  304. .Ss Predefined Task Queues
  305. The system provides four global taskqueues,
  306. .Va taskqueue_fast ,
  307. .Va taskqueue_swi ,
  308. .Va taskqueue_swi_giant ,
  309. and
  310. .Va taskqueue_thread .
  311. The
  312. .Va taskqueue_fast
  313. queue is for swi handlers dispatched from fast interrupt handlers,
  314. where sleep mutexes cannot be used.
  315. The swi taskqueues are run via a software interrupt mechanism.
  316. The
  317. .Va taskqueue_swi
  318. queue runs without the protection of the
  319. .Va Giant
  320. kernel lock, and the
  321. .Va taskqueue_swi_giant
  322. queue runs with the protection of the
  323. .Va Giant
  324. kernel lock.
  325. The thread taskqueue
  326. .Va taskqueue_thread
  327. runs in a kernel thread context, and tasks run from this thread do
  328. not run under the
  329. .Va Giant
  330. kernel lock.
  331. If the caller wants to run under
  332. .Va Giant ,
  333. he should explicitly acquire and release
  334. .Va Giant
  335. in his taskqueue handler routine.
  336. .Pp
  337. To use these queues,
  338. call
  339. .Fn taskqueue_enqueue
  340. with the value of the global taskqueue variable for the queue you wish to
  341. use
  342. .Va ( taskqueue_swi ,
  343. .Va taskqueue_swi_giant ,
  344. or
  345. .Va taskqueue_thread ) .
  346. Use
  347. .Fn taskqueue_enqueue_fast
  348. for the global taskqueue variable
  349. .Va taskqueue_fast .
  350. .Pp
  351. The software interrupt queues can be used,
  352. for instance, for implementing interrupt handlers which must perform a
  353. significant amount of processing in the handler.
  354. The hardware interrupt handler would perform minimal processing of the
  355. interrupt and then enqueue a task to finish the work.
  356. This reduces to a minimum
  357. the amount of time spent with interrupts disabled.
  358. .Pp
  359. The thread queue can be used, for instance, by interrupt level routines
  360. that need to call kernel functions that do things that can only be done
  361. from a thread context.
  362. (e.g., call malloc with the M_WAITOK flag.)
  363. .Pp
  364. Note that tasks queued on shared taskqueues such as
  365. .Va taskqueue_swi
  366. may be delayed an indeterminate amount of time before execution.
  367. If queueing delays cannot be tolerated then a private taskqueue should
  368. be created with a dedicated processing thread.
  369. .Sh SEE ALSO
  370. .Xr ithread 9 ,
  371. .Xr kthread 9 ,
  372. .Xr swi 9
  373. .Sh HISTORY
  374. This interface first appeared in
  375. .Fx 5.0 .
  376. There is a similar facility called work_queue in the Linux kernel.
  377. .Sh AUTHORS
  378. This manual page was written by
  379. .An Doug Rabson .