xref: /NextBSD/lib/libdispatch/private/queue_private.h (revision 33da5adc555b3bc29986eeadca03829e4ad06b1e)
1 /*
2  * Copyright (c) 2008-2013 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 /*
22  * IMPORTANT: This header file describes INTERNAL interfaces to libdispatch
23  * which are subject to change in future releases of Mac OS X. Any applications
24  * relying on these interfaces WILL break.
25  */
26 
27 #ifndef __DISPATCH_QUEUE_PRIVATE__
28 #define __DISPATCH_QUEUE_PRIVATE__
29 
30 #ifndef __DISPATCH_INDIRECT__
31 #error "Please #include <dispatch/private.h> instead of this file directly."
32 #include <dispatch/base.h> // for HeaderDoc
33 #endif
34 
35 __BEGIN_DECLS
36 
37 /*!
38  * @enum dispatch_queue_flags_t
39  *
40  * @constant DISPATCH_QUEUE_OVERCOMMIT
41  * The queue will create a new thread for invoking blocks, regardless of how
42  * busy the computer is.
43  */
44 enum {
45 	DISPATCH_QUEUE_OVERCOMMIT = 0x2ull,
46 };
47 
48 #define DISPATCH_QUEUE_FLAGS_MASK (DISPATCH_QUEUE_OVERCOMMIT)
49 
50 /*!
51  * @function dispatch_queue_attr_make_with_overcommit
52  *
53  * @discussion
54  * Returns a dispatch queue attribute value with the overcommit flag set to the
55  * specified value.
56  *
57  * @param attr
58  * A queue attribute value to be combined with the overcommit flag, or NULL.
59  *
60  * @param overcommit
61  * Boolean overcommit flag.
62  *
63  * @return
64  * Returns an attribute value which may be provided to dispatch_queue_create().
65  * This new value combines the attributes specified by the 'attr' parameter and
66  * the overcommit flag.
67  */
68 __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0)
69 DISPATCH_EXPORT DISPATCH_WARN_RESULT DISPATCH_PURE DISPATCH_NOTHROW
70 dispatch_queue_attr_t
71 dispatch_queue_attr_make_with_overcommit(dispatch_queue_attr_t attr,
72 		bool overcommit);
73 
74 /*!
75  * @typedef dispatch_queue_priority_t
76  *
77  * @constant DISPATCH_QUEUE_PRIORITY_NON_INTERACTIVE
78  * Items dispatched to the queue will run at non-interactive priority.
79  * This priority level is intended for user-initiated application activity that
80  * is long-running and CPU or IO intensive and that the user is actively waiting
81  * on, but that should not interfere with interactive use of the application.
82  */
83 #define DISPATCH_QUEUE_PRIORITY_NON_INTERACTIVE INT8_MIN
84 
85 /*!
86  * @function dispatch_queue_set_width
87  *
88  * @abstract
89  * Set the width of concurrency for a given queue. The width of a serial queue
90  * is one.
91  *
92  * @discussion
93  * This SPI is DEPRECATED and will be removed in a future release.
94  * Uses of this SPI to make a queue concurrent by setting its width to LONG_MAX
95  * should be replaced by passing DISPATCH_QUEUE_CONCURRENT to
96  * dispatch_queue_create().
97  * Uses of this SPI to limit queue concurrency are not recommended and should
98  * be replaced by alternative mechanisms such as a dispatch semaphore created
99  * with the desired concurrency width.
100  *
101  * @param queue
102  * The queue to adjust. Passing the main queue or a global concurrent queue
103  * will be ignored.
104  *
105  * @param width
106  * The new maximum width of concurrency depending on available resources.
107  * If zero is passed, then the value is promoted to one.
108  * Negative values are magic values that map to automatic width values.
109  * Unknown negative values default to DISPATCH_QUEUE_WIDTH_MAX_LOGICAL_CPUS.
110  */
111 #define DISPATCH_QUEUE_WIDTH_ACTIVE_CPUS		-1
112 #define DISPATCH_QUEUE_WIDTH_MAX_PHYSICAL_CPUS	-2
113 #define DISPATCH_QUEUE_WIDTH_MAX_LOGICAL_CPUS	-3
114 
115 __OSX_AVAILABLE_BUT_DEPRECATED_MSG(__MAC_10_6,__MAC_10_10,__IPHONE_4_0,__IPHONE_8_0, \
116 		"Use dispatch_queue_create(name, DISPATCH_QUEUE_CONCURRENT) instead")
117 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
118 void
119 dispatch_queue_set_width(dispatch_queue_t dq, long width);
120 
121 /*!
122  * @function dispatch_queue_create_with_target
123  *
124  * @abstract
125  * Creates a new dispatch queue with a specified target queue.
126  *
127  * @discussion
128  * Dispatch queues created with the DISPATCH_QUEUE_SERIAL or a NULL attribute
129  * invoke blocks serially in FIFO order.
130  *
131  * Dispatch queues created with the DISPATCH_QUEUE_CONCURRENT attribute may
132  * invoke blocks concurrently (similarly to the global concurrent queues, but
133  * potentially with more overhead), and support barrier blocks submitted with
134  * the dispatch barrier API, which e.g. enables the implementation of efficient
135  * reader-writer schemes.
136  *
137  * When a dispatch queue is no longer needed, it should be released with
138  * dispatch_release(). Note that any pending blocks submitted to a queue will
139  * hold a reference to that queue. Therefore a queue will not be deallocated
140  * until all pending blocks have finished.
141  *
142  * @param label
143  * A string label to attach to the queue.
144  * This parameter is optional and may be NULL.
145  *
146  * @param attr
147  * DISPATCH_QUEUE_SERIAL, DISPATCH_QUEUE_CONCURRENT, or the result of a call to
148  * the function dispatch_queue_attr_make_with_qos_class().
149  *
150  * @param target
151  * The target queue for the newly created queue. The target queue is retained.
152  * If this parameter is DISPATCH_TARGET_QUEUE_DEFAULT, sets the queue's target
153  * queue to the default target queue for the given queue type.
154  *
155  * @result
156  * The newly created dispatch queue.
157  */
158 __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0)
159 DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT
160 DISPATCH_NOTHROW
161 dispatch_queue_t
162 dispatch_queue_create_with_target(const char *label,
163 	dispatch_queue_attr_t attr, dispatch_queue_t target);
164 
165 #ifdef __BLOCKS__
166 /*!
167  * @function dispatch_pthread_root_queue_create
168  *
169  * @abstract
170  * Creates a new concurrent dispatch root queue with a pthread-based pool of
171  * worker threads owned by the application.
172  *
173  * @discussion
174  * Dispatch pthread root queues are similar to the global concurrent dispatch
175  * queues in that they invoke blocks concurrently, however the blocks are not
176  * executed on ordinary worker threads but use a dedicated pool of pthreads not
177  * shared with the global queues or any other pthread root queues.
178  *
179  * NOTE: this is a special-purpose facility that should only be used in very
180  * limited circumstances, in almost all cases the global concurrent queues
181  * should be preferred. While this facility allows for more flexibility in
182  * configuring worker threads for special needs it comes at the cost of
183  * increased overall memory usage due to reduced thread sharing and higher
184  * latency in worker thread bringup.
185  *
186  * Dispatch pthread root queues do not support suspension, application context
187  * and change of width or of target queue. They can however be used as the
188  * target queue for serial or concurrent queues obtained via
189  * dispatch_queue_create() or dispatch_queue_create_with_target(), which
190  * enables the blocks submitted to those queues to be processed on the root
191  * queue's pthread pool.
192  *
193  * When a dispatch pthread root queue is no longer needed, it should be
194  * released with dispatch_release(). Existing worker pthreads and pending blocks
195  * submitted to the root queue will hold a reference to the queue so it will not
196  * be deallocated until all blocks have finished and worker threads exited.
197  *
198  * @param label
199  * A string label to attach to the queue.
200  * This parameter is optional and may be NULL.
201  *
202  * @param flags
203  * Pass flags value returned by dispatch_pthread_root_queue_flags_pool_size()
204  * or 0 if unused.
205  *
206  * @param attr
207  * Attributes passed to pthread_create(3) when creating worker pthreads. This
208  * parameter is copied and can be destroyed after this call returns.
209  * This parameter is optional and may be NULL.
210  *
211  * @param configure
212  * Configuration block called on newly created worker pthreads before any blocks
213  * for the root queue are executed. The block may configure the current thread
214  * as needed.
215  * This parameter is optional and may be NULL.
216  *
217  * @result
218  * The newly created dispatch pthread root queue.
219  */
220 __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_6_0)
221 DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT
222 DISPATCH_NOTHROW
223 dispatch_queue_t
224 dispatch_pthread_root_queue_create(const char *label, unsigned long flags,
225 	const pthread_attr_t *attr, dispatch_block_t configure);
226 
227 /*!
228  * @function dispatch_pthread_root_queue_flags_pool_size
229  *
230  * @abstract
231  * Returns flags argument to pass to dispatch_pthread_root_queue_create() to
232  * specify the maximum size of the pthread pool to use for a pthread root queue.
233  *
234  * @param pool_size
235  * Maximum size of the pthread pool to use for the root queue. The number of
236  * pthreads created for this root queue will never exceed this number but there
237  * is no guarantee that the specified number will be reached.
238  * Pass 0 to specify that a default pool size determined by the system should
239  * be used.
240  *
241  * @result
242  * The flags argument to pass to dispatch_pthread_root_queue_create().
243  */
244 DISPATCH_INLINE DISPATCH_ALWAYS_INLINE
245 unsigned long
dispatch_pthread_root_queue_flags_pool_size(uint8_t pool_size)246 dispatch_pthread_root_queue_flags_pool_size(uint8_t pool_size)
247 {
248 	#define _DISPATCH_PTHREAD_ROOT_QUEUE_FLAG_POOL_SIZE (0x80000000ul)
249 	return (_DISPATCH_PTHREAD_ROOT_QUEUE_FLAG_POOL_SIZE |
250 			(unsigned long)pool_size);
251 }
252 
253 #endif /* __BLOCKS__ */
254 
255 /*!
256  * @constant DISPATCH_APPLY_CURRENT_ROOT_QUEUE
257  * @discussion Constant to pass to the dispatch_apply() and dispatch_apply_f()
258  * functions to indicate that the root queue for the current thread should be
259  * used (i.e. one of the global concurrent queues or a queue created with
260  * dispatch_pthread_root_queue_create()). If there is no such queue, the
261  * default priority global concurrent queue will be used.
262  */
263 #define DISPATCH_APPLY_CURRENT_ROOT_QUEUE NULL
264 
265 /*!
266  * @function dispatch_assert_queue
267  *
268  * @abstract
269  * Verifies that the current block is executing on a certain dispatch queue.
270  *
271  * @discussion
272  * Some code expects to be run on a specific dispatch queue. This function
273  * verifies that expectation for debugging.
274  *
275  * This function will only return if the currently executing block was submitted
276  * to the specified queue or to any queue targeting it (see
277  * dispatch_set_target_queue()). Otherwise, it logs an explanation to the system
278  * log, then terminates the application.
279  *
280  * When dispatch_assert_queue() is called outside of the context of a
281  * submitted block, its behavior is undefined.
282  *
283  * Passing the result of dispatch_get_main_queue() to this function verifies
284  * that the current block was submitted to the main queue or to a queue
285  * targeting it.
286  * IMPORTANT: this is NOT the same as verifying that the current block is
287  * executing on the main thread.
288  *
289  * The variant dispatch_assert_queue_debug() is compiled out when the
290  * preprocessor macro NDEBUG is defined. (See also assert(3)).
291  *
292  * @param queue
293  * The dispatch queue that the current block is expected to run on.
294  * The result of passing NULL in this parameter is undefined.
295  */
296 __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0)
297 DISPATCH_EXPORT DISPATCH_NONNULL1
298 void
299 dispatch_assert_queue(dispatch_queue_t queue);
300 
301 /*!
302  * @function dispatch_assert_queue_not
303  *
304  * @abstract
305  * Verifies that the current block is not executing on a certain dispatch queue.
306  *
307  * @discussion
308  * This function is the equivalent of dispatch_queue_assert() with the test for
309  * equality inverted. See discussion there.
310  *
311  * The variant dispatch_assert_queue_not_debug() is compiled out when the
312  * preprocessor macro NDEBUG is defined. (See also assert(3)).
313  *
314  * @param queue
315  * The dispatch queue that the current block is expected not to run on.
316  * The result of passing NULL in this parameter is undefined.
317  */
318 __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0)
319 DISPATCH_EXPORT DISPATCH_NONNULL1
320 void
321 dispatch_assert_queue_not(dispatch_queue_t queue);
322 
323 #ifdef NDEBUG
324 #define dispatch_assert_queue_debug(q) ((void)0)
325 #define dispatch_assert_queue_not_debug(q) ((void)0)
326 #else
327 #define dispatch_assert_queue_debug(q) dispatch_assert_queue(q)
328 #define dispatch_assert_queue_not_debug(q) dispatch_assert_queue_not(q)
329 #endif
330 
331 __END_DECLS
332 
333 #endif
334