workloop_private.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440
  1. /*
  2. * Copyright (c) 2017-2018 Apple Inc. All rights reserved.
  3. *
  4. * @APPLE_APACHE_LICENSE_HEADER_START@
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the "License");
  7. * you may not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. *
  18. * @APPLE_APACHE_LICENSE_HEADER_END@
  19. */
  20. /*
  21. * IMPORTANT: This header file describes INTERNAL interfaces to libdispatch
  22. * which are subject to change in future releases of Mac OS X. Any applications
  23. * relying on these interfaces WILL break.
  24. */
  25. #ifndef __DISPATCH_WORKLOOP_PRIVATE__
  26. #define __DISPATCH_WORKLOOP_PRIVATE__
  27. #ifndef __DISPATCH_INDIRECT__
  28. #error "Please #include <dispatch/private.h> instead of this file directly."
  29. #include <dispatch/base.h> // for HeaderDoc
  30. #endif
  31. /******************************************************************************\
  32. *
  33. * THIS FILE IS AN IN-PROGRESS INTERFACE THAT IS SUBJECT TO CHANGE
  34. *
  35. \******************************************************************************/
  36. DISPATCH_ASSUME_NONNULL_BEGIN
  37. __BEGIN_DECLS
  38. /*!
  39. * @typedef dispatch_workloop_t
  40. *
  41. * @abstract
  42. * Dispatch workloops invoke workitems submitted to them in priority order.
  43. *
  44. * @discussion
  45. * A dispatch workloop is a flavor of dispatch_queue_t that is a priority
  46. * ordered queue (using the QOS class of the submitted workitems as the
  47. * ordering).
  48. *
  49. * Between each workitem invocation, the workloop will evaluate whether higher
  50. * priority workitems have since been submitted and execute these first.
  51. *
  52. * Serial queues targeting a workloop maintain FIFO execution of their
  53. * workitems. However, the workloop may reorder workitems submitted to
  54. * independent serial queues targeting it with respect to each other,
  55. * based on their priorities.
  56. *
  57. * A dispatch workloop is a "subclass" of dispatch_queue_t which can be passed
  58. * to all APIs accepting a dispatch queue, except for functions from the
  59. * dispatch_sync() family. dispatch_async_and_wait() must be used for workloop
  60. * objects. Functions from the dispatch_sync() family on queues targeting
  61. * a workloop are still permitted but discouraged for performance reasons.
  62. */
  63. #if defined(__DISPATCH_BUILDING_DISPATCH__) && !defined(__OBJC__)
  64. typedef struct dispatch_workloop_s *dispatch_workloop_t;
  65. #else
  66. DISPATCH_DECL_SUBCLASS(dispatch_workloop, dispatch_queue);
  67. #endif
  68. /*!
  69. * @function dispatch_workloop_create
  70. *
  71. * @abstract
  72. * Creates a new dispatch workloop to which workitems may be submitted.
  73. *
  74. * @param label
  75. * A string label to attach to the workloop.
  76. *
  77. * @result
  78. * The newly created dispatch workloop.
  79. */
  80. API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
  81. DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT
  82. DISPATCH_NOTHROW
  83. dispatch_workloop_t
  84. dispatch_workloop_create(const char *_Nullable label);
  85. /*!
  86. * @function dispatch_workloop_create_inactive
  87. *
  88. * @abstract
  89. * Creates a new inactive dispatch workloop that can be setup and then
  90. * activated.
  91. *
  92. * @discussion
  93. * Creating an inactive workloop allows for it to receive further configuration
  94. * before it is activated, and workitems can be submitted to it.
  95. *
  96. * Submitting workitems to an inactive workloop is undefined and will cause the
  97. * process to be terminated.
  98. *
  99. * @param label
  100. * A string label to attach to the workloop.
  101. *
  102. * @result
  103. * The newly created dispatch workloop.
  104. */
  105. API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
  106. DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT
  107. DISPATCH_NOTHROW
  108. dispatch_workloop_t
  109. dispatch_workloop_create_inactive(const char *_Nullable label);
  110. /*!
  111. * @function dispatch_workloop_set_autorelease_frequency
  112. *
  113. * @abstract
  114. * Sets the autorelease frequency of the workloop.
  115. *
  116. * @discussion
  117. * See dispatch_queue_attr_make_with_autorelease_frequency().
  118. * The default policy for a workloop is
  119. * DISPATCH_AUTORELEASE_FREQUENCY_WORK_ITEM.
  120. *
  121. * @param workloop
  122. * The dispatch workloop to modify.
  123. *
  124. * This workloop must be inactive, passing an activated object is undefined
  125. * and will cause the process to be terminated.
  126. *
  127. * @param frequency
  128. * The requested autorelease frequency.
  129. */
  130. API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
  131. DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
  132. void
  133. dispatch_workloop_set_autorelease_frequency(dispatch_workloop_t workloop,
  134. dispatch_autorelease_frequency_t frequency);
  135. DISPATCH_ENUM(dispatch_workloop_param_flags, uint64_t,
  136. DISPATCH_WORKLOOP_NONE DISPATCH_ENUM_API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0)) = 0x0,
  137. DISPATCH_WORKLOOP_FIXED_PRIORITY DISPATCH_ENUM_API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0)) = 0x1,
  138. );
  139. /*!
  140. * @function dispatch_workloop_set_qos_class_floor
  141. *
  142. * @abstract
  143. * Sets the QOS class floor of a workloop.
  144. *
  145. * @discussion
  146. * See dispatch_set_qos_class_floor().
  147. *
  148. * This function is strictly equivalent to dispatch_set_qos_class_floor() but
  149. * allows to pass extra flags.
  150. *
  151. * Using both dispatch_workloop_set_scheduler_priority() and
  152. * dispatch_set_qos_class_floor() or dispatch_workloop_set_qos_class_floor()
  153. * is undefined and will cause the process to be terminated.
  154. *
  155. * @param workloop
  156. * The dispatch workloop to modify.
  157. *
  158. * This workloop must be inactive, passing an activated object is undefined
  159. * and will cause the process to be terminated.
  160. */
  161. API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
  162. DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
  163. void
  164. dispatch_workloop_set_qos_class_floor(dispatch_workloop_t workloop,
  165. dispatch_qos_class_t qos, int relpri, dispatch_workloop_param_flags_t flags);
  166. /*!
  167. * @function dispatch_workloop_set_scheduler_priority
  168. *
  169. * @abstract
  170. * Sets the scheduler priority for a dispatch workloop.
  171. *
  172. * @discussion
  173. * This sets the scheduler priority of the threads that the runtime will bring
  174. * up to service this workloop.
  175. *
  176. * QOS propagation still functions on these workloops, but its effect on the
  177. * priority of the thread brought up to service this workloop is ignored.
  178. *
  179. * Using both dispatch_workloop_set_scheduler_priority() and
  180. * dispatch_set_qos_class_floor() or dispatch_workloop_set_qos_class_floor()
  181. * is undefined and will cause the process to be terminated.
  182. *
  183. * @param workloop
  184. * The dispatch workloop to modify.
  185. *
  186. * This workloop must be inactive, passing an activated object is undefined
  187. * and will cause the process to be terminated.
  188. */
  189. API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
  190. DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
  191. void
  192. dispatch_workloop_set_scheduler_priority(dispatch_workloop_t workloop,
  193. int priority, dispatch_workloop_param_flags_t flags);
  194. /*!
  195. * @function dispatch_workloop_set_cpupercent
  196. *
  197. * @abstract
  198. * Sets the cpu percent and refill attributes for a dispatch workloop.
  199. *
  200. * @discussion
  201. * This should only used if the workloop was also setup with the
  202. * DISPATCH_WORKLOOP_FIXED_PRIORITY flag as a safe guard against
  203. * busy loops that could starve the rest of the system forever.
  204. *
  205. * If DISPATCH_WORKLOOP_FIXED_PRIORITY wasn't passed, using this function is
  206. * undefined and will cause the process to be terminated.
  207. *
  208. * @param workloop
  209. * The dispatch workloop to modify.
  210. *
  211. * This workloop must be inactive, passing an activated object is undefined
  212. * and will cause the process to be terminated.
  213. */
  214. API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
  215. DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
  216. void
  217. dispatch_workloop_set_cpupercent(dispatch_workloop_t workloop, uint8_t percent,
  218. uint32_t refillms);
  219. /*!
  220. * @function dispatch_workloop_is_current()
  221. *
  222. * @abstract
  223. * Returns whether the current thread has been made by the runtime to service
  224. * this workloop.
  225. *
  226. * @discussion
  227. * Note that when using <code>dispatch_async_and_wait(workloop, ^{ ... })</code>
  228. * then <code>workloop</code> will be seen as the "current" one by the submitted
  229. * workitem, but that is not the case when using dispatch_sync() on a queue
  230. * targeting the workloop.
  231. */
  232. API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
  233. DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
  234. bool
  235. dispatch_workloop_is_current(dispatch_workloop_t workloop);
  236. /*!
  237. * @function dispatch_workloop_copy_current()
  238. *
  239. * @abstract
  240. * Returns a copy of the workoop that is being serviced on the calling thread
  241. * if any.
  242. *
  243. * @discussion
  244. * If the thread is not a workqueue thread, or is not servicing a dispatch
  245. * workloop, then NULL is returned.
  246. *
  247. * This returns a retained object that must be released with dispatch_release().
  248. */
  249. API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
  250. DISPATCH_EXPORT DISPATCH_RETURNS_RETAINED DISPATCH_NOTHROW
  251. dispatch_workloop_t _Nullable
  252. dispatch_workloop_copy_current(void);
  253. // Equivalent to dispatch_workloop_set_qos_class_floor(workoop, qos, 0, flags)
  254. API_DEPRECATED_WITH_REPLACEMENT("dispatch_workloop_set_qos_class_floor",
  255. macos(10.14,10.14), ios(12.0,12.0), tvos(12.0,12.0), watchos(5.0,5.0))
  256. DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
  257. void
  258. dispatch_workloop_set_qos_class(dispatch_workloop_t workloop,
  259. dispatch_qos_class_t qos, dispatch_workloop_param_flags_t flags);
  260. API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
  261. DISPATCH_EXPORT DISPATCH_NOTHROW
  262. bool
  263. _dispatch_workloop_should_yield_4NW(void);
  264. /*!
  265. * @function dispatch_async_and_wait
  266. *
  267. * @abstract
  268. * Submits a block for synchronous execution on a dispatch queue.
  269. *
  270. * @discussion
  271. * Submits a workitem to a dispatch queue like dispatch_async(), however
  272. * dispatch_async_and_wait() will not return until the workitem has finished.
  273. *
  274. * Like functions of the dispatch_sync family, dispatch_async_and_wait() is
  275. * subject to dead-lock (See dispatch_sync() for details).
  276. *
  277. * However, dispatch_async_and_wait() differs from functions of the
  278. * dispatch_sync family in two fundamental ways: how it respects queue
  279. * attributes and how it chooses the execution context invoking the workitem.
  280. *
  281. * <b>Differences with dispatch_sync()</b>
  282. *
  283. * Work items submitted to a queue with dispatch_async_and_wait() observe all
  284. * queue attributes of that queue when invoked (inluding autorelease frequency
  285. * or QOS class).
  286. *
  287. * When the runtime has brought up a thread to invoke the asynchronous workitems
  288. * already submitted to the specified queue, that servicing thread will also be
  289. * used to execute synchronous work submitted to the queue with
  290. * dispatch_async_and_wait().
  291. *
  292. * However, if the runtime has not brought up a thread to service the specified
  293. * queue (because it has no workitems enqueued, or only synchronous workitems),
  294. * then dispatch_async_and_wait() will invoke the workitem on the calling thread,
  295. * similar to the behaviour of functions in the dispatch_sync family.
  296. *
  297. * As an exception, if the queue the work is submitted to doesn't target
  298. * a global concurrent queue (for example because it targets the main queue),
  299. * then the workitem will never be invoked by the thread calling
  300. * dispatch_async_and_wait().
  301. *
  302. * In other words, dispatch_async_and_wait() is similar to submitting
  303. * a dispatch_block_create()d workitem to a queue and then waiting on it, as
  304. * shown in the code example below. However, dispatch_async_and_wait() is
  305. * significantly more efficient when a new thread is not required to execute
  306. * the workitem (as it will use the stack of the submitting thread instead of
  307. * requiring heap allocations).
  308. *
  309. * <code>
  310. * dispatch_block_t b = dispatch_block_create(0, block);
  311. * dispatch_async(queue, b);
  312. * dispatch_block_wait(b, DISPATCH_TIME_FOREVER);
  313. * Block_release(b);
  314. * </code>
  315. *
  316. * @param queue
  317. * The target dispatch queue to which the block is submitted.
  318. * The result of passing NULL in this parameter is undefined.
  319. *
  320. * @param block
  321. * The block to be invoked on the target dispatch queue.
  322. * The result of passing NULL in this parameter is undefined.
  323. */
  324. #ifdef __BLOCKS__
  325. API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
  326. DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
  327. void
  328. dispatch_async_and_wait(dispatch_queue_t queue,
  329. DISPATCH_NOESCAPE dispatch_block_t block);
  330. #endif
  331. /*!
  332. * @function dispatch_async_and_wait_f
  333. *
  334. * @abstract
  335. * Submits a function for synchronous execution on a dispatch queue.
  336. *
  337. * @discussion
  338. * See dispatch_async_and_wait() for details.
  339. *
  340. * @param queue
  341. * The target dispatch queue to which the function is submitted.
  342. * The result of passing NULL in this parameter is undefined.
  343. *
  344. * @param context
  345. * The application-defined context parameter to pass to the function.
  346. *
  347. * @param work
  348. * The application-defined function to invoke on the target queue. The first
  349. * parameter passed to this function is the context provided to
  350. * dispatch_async_and_wait_f().
  351. * The result of passing NULL in this parameter is undefined.
  352. */
  353. API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
  354. DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NOTHROW
  355. void
  356. dispatch_async_and_wait_f(dispatch_queue_t queue,
  357. void *_Nullable context, dispatch_function_t work);
  358. /*!
  359. * @function dispatch_barrier_async_and_wait
  360. *
  361. * @abstract
  362. * Submits a block for synchronous execution on a dispatch queue.
  363. *
  364. * @discussion
  365. * Submits a block to a dispatch queue like dispatch_async_and_wait(), but marks
  366. * that block as a barrier (relevant only on DISPATCH_QUEUE_CONCURRENT
  367. * queues).
  368. *
  369. * @param queue
  370. * The target dispatch queue to which the block is submitted.
  371. * The result of passing NULL in this parameter is undefined.
  372. *
  373. * @param work
  374. * The application-defined block to invoke on the target queue.
  375. * The result of passing NULL in this parameter is undefined.
  376. */
  377. #ifdef __BLOCKS__
  378. API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
  379. DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
  380. void
  381. dispatch_barrier_async_and_wait(dispatch_queue_t queue,
  382. DISPATCH_NOESCAPE dispatch_block_t block);
  383. #endif
  384. /*!
  385. * @function dispatch_barrier_async_and_wait_f
  386. *
  387. * @abstract
  388. * Submits a function for synchronous execution on a dispatch queue.
  389. *
  390. * @discussion
  391. * Submits a function to a dispatch queue like dispatch_async_and_wait_f(), but
  392. * marks that function as a barrier (relevant only on DISPATCH_QUEUE_CONCURRENT
  393. * queues).
  394. *
  395. * @param queue
  396. * The target dispatch queue to which the function is submitted.
  397. * The result of passing NULL in this parameter is undefined.
  398. *
  399. * @param context
  400. * The application-defined context parameter to pass to the function.
  401. *
  402. * @param work
  403. * The application-defined function to invoke on the target queue. The first
  404. * parameter passed to this function is the context provided to
  405. * dispatch_barrier_async_and_wait_f().
  406. * The result of passing NULL in this parameter is undefined.
  407. */
  408. API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
  409. DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NOTHROW
  410. void
  411. dispatch_barrier_async_and_wait_f(dispatch_queue_t queue,
  412. void *_Nullable context, dispatch_function_t work);
  413. __END_DECLS
  414. DISPATCH_ASSUME_NONNULL_END
  415. #endif