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 */
44enum {
45	DISPATCH_QUEUE_OVERCOMMIT = 0x2ull,
46};
47
48#define DISPATCH_QUEUE_FLAGS_MASK (DISPATCH_QUEUE_OVERCOMMIT)
49
50/*!
51 * @typedef dispatch_queue_priority_t
52 *
53 * @constant DISPATCH_QUEUE_PRIORITY_NON_INTERACTIVE
54 * Items dispatched to the queue will run at non-interactive priority.
55 * This priority level is intended for user-initiated application activity that
56 * is long-running and CPU or IO intensive and that the user is actively waiting
57 * on, but that should not interfere with interactive use of the application.
58 */
59#define DISPATCH_QUEUE_PRIORITY_NON_INTERACTIVE INT8_MIN
60
61/*!
62 * @function dispatch_queue_set_width
63 *
64 * @abstract
65 * Set the width of concurrency for a given queue. The width of a serial queue
66 * is one.
67 *
68 * @discussion
69 * This SPI is DEPRECATED and will be removed in a future release.
70 * Uses of this SPI to make a queue concurrent by setting its width to LONG_MAX
71 * should be replaced by passing DISPATCH_QUEUE_CONCURRENT to
72 * dispatch_queue_create().
73 * Uses of this SPI to limit queue concurrency are not recommended and should
74 * be replaced by alternative mechanisms such as a dispatch semaphore created
75 * with the desired concurrency width.
76 *
77 * @param queue
78 * The queue to adjust. Passing the main queue or a global concurrent queue
79 * will be ignored.
80 *
81 * @param width
82 * The new maximum width of concurrency depending on available resources.
83 * If zero is passed, then the value is promoted to one.
84 * Negative values are magic values that map to automatic width values.
85 * Unknown negative values default to DISPATCH_QUEUE_WIDTH_MAX_LOGICAL_CPUS.
86 */
87#define DISPATCH_QUEUE_WIDTH_ACTIVE_CPUS		-1
88#define DISPATCH_QUEUE_WIDTH_MAX_PHYSICAL_CPUS	-2
89#define DISPATCH_QUEUE_WIDTH_MAX_LOGICAL_CPUS	-3
90
91__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0)
92DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
93void
94dispatch_queue_set_width(dispatch_queue_t dq, long width); // DEPRECATED
95
96/*!
97 * @function dispatch_queue_create_with_target
98 *
99 * @abstract
100 * Creates a new dispatch queue with a specified target queue.
101 *
102 * @discussion
103 * Dispatch queues created with the DISPATCH_QUEUE_SERIAL or a NULL attribute
104 * invoke blocks serially in FIFO order.
105 *
106 * Dispatch queues created with the DISPATCH_QUEUE_CONCURRENT attribute may
107 * invoke blocks concurrently (similarly to the global concurrent queues, but
108 * potentially with more overhead), and support barrier blocks submitted with
109 * the dispatch barrier API, which e.g. enables the implementation of efficient
110 * reader-writer schemes.
111 *
112 * When a dispatch queue is no longer needed, it should be released with
113 * dispatch_release(). Note that any pending blocks submitted to a queue will
114 * hold a reference to that queue. Therefore a queue will not be deallocated
115 * until all pending blocks have finished.
116 *
117 * @param label
118 * A string label to attach to the queue.
119 * This parameter is optional and may be NULL.
120 *
121 * @param attr
122 * DISPATCH_QUEUE_SERIAL or DISPATCH_QUEUE_CONCURRENT.
123 *
124 * @param target
125 * The target queue for the newly created queue. The target queue is retained.
126 * If this parameter is DISPATCH_TARGET_QUEUE_DEFAULT, sets the queue's target
127 * queue to the default target queue for the given queue type.
128 *
129 * @result
130 * The newly created dispatch queue.
131 */
132__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0)
133DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT
134DISPATCH_NOTHROW
135dispatch_queue_t
136dispatch_queue_create_with_target(const char *label,
137	dispatch_queue_attr_t attr, dispatch_queue_t target);
138
139#ifdef __BLOCKS__
140/*!
141 * @function dispatch_pthread_root_queue_create
142 *
143 * @abstract
144 * Creates a new concurrent dispatch root queue with a pthread-based pool of
145 * worker threads owned by the application.
146 *
147 * @discussion
148 * Dispatch pthread root queues are similar to the global concurrent dispatch
149 * queues in that they invoke blocks concurrently, however the blocks are not
150 * executed on ordinary worker threads but use a dedicated pool of pthreads not
151 * shared with the global queues or any other pthread root queues.
152 *
153 * NOTE: this is a special-purpose facility that should only be used in very
154 * limited circumstances, in almost all cases the global concurrent queues
155 * should be preferred. While this facility allows for more flexibility in
156 * configuring worker threads for special needs it comes at the cost of
157 * increased overall memory usage due to reduced thread sharing and higher
158 * latency in worker thread bringup.
159 *
160 * Dispatch pthread root queues do not support suspension, application context
161 * and change of width or of target queue. They can however be used as the
162 * target queue for serial or concurrent queues obtained via
163 * dispatch_queue_create() or dispatch_queue_create_with_target(), which
164 * enables the blocks submitted to those queues to be processed on the root
165 * queue's pthread pool.
166 *
167 * When a dispatch pthread root queue is no longer needed, it should be
168 * released with dispatch_release(). Existing worker pthreads and pending blocks
169 * submitted to the root queue will hold a reference to the queue so it will not
170 * be deallocated until all blocks have finished and worker threads exited.
171 *
172 * @param label
173 * A string label to attach to the queue.
174 * This parameter is optional and may be NULL.
175 *
176 * @param flags
177 * Reserved for future use. Passing any value other than zero may result in
178 * a NULL return value.
179 *
180 * @param attr
181 * Attributes passed to pthread_create(3) when creating worker pthreads. This
182 * parameter is copied and can be destroyed after this call returns.
183 * This parameter is optional and may be NULL.
184 *
185 * @param configure
186 * Configuration block called on newly created worker pthreads before any blocks
187 * for the root queue are executed. The block may configure the current thread
188 * as needed.
189 * This parameter is optional and may be NULL.
190 *
191 * @result
192 * The newly created dispatch pthread root queue.
193 */
194__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_6_0)
195DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT
196DISPATCH_NOTHROW
197dispatch_queue_t
198dispatch_pthread_root_queue_create(const char *label, unsigned long flags,
199	const pthread_attr_t *attr, dispatch_block_t configure);
200#endif /* __BLOCKS__ */
201
202/*!
203 * @constant DISPATCH_APPLY_CURRENT_ROOT_QUEUE
204 * @discussion Constant to pass to the dispatch_apply() and dispatch_apply_f()
205 * functions to indicate that the root queue for the current thread should be
206 * used (i.e. one of the global concurrent queues or a queue created with
207 * dispatch_pthread_root_queue_create()). If there is no such queue, the
208 * default priority global concurrent queue will be used.
209 */
210#define DISPATCH_APPLY_CURRENT_ROOT_QUEUE NULL
211
212#if !TARGET_OS_WIN32
213__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0)
214DISPATCH_EXPORT const struct dispatch_queue_offsets_s {
215	// always add new fields at the end
216	const uint16_t dqo_version;
217	const uint16_t dqo_label;
218	const uint16_t dqo_label_size;
219	const uint16_t dqo_flags;
220	const uint16_t dqo_flags_size;
221	const uint16_t dqo_serialnum;
222	const uint16_t dqo_serialnum_size;
223	const uint16_t dqo_width;
224	const uint16_t dqo_width_size;
225	const uint16_t dqo_running;
226	const uint16_t dqo_running_size;
227} dispatch_queue_offsets;
228#endif
229
230/*!
231 * @function dispatch_assert_queue
232 *
233 * @abstract
234 * Verifies that the current block is executing on a certain dispatch queue.
235 *
236 * @discussion
237 * Some code expects to be run on a specific dispatch queue. This function
238 * verifies that expectation for debugging.
239 *
240 * This function will only return if the currently executing block was submitted
241 * to the specified queue or to any queue targeting it (see
242 * dispatch_set_target_queue()). Otherwise, it logs an explanation to the system
243 * log, then terminates the application.
244 *
245 * When dispatch_assert_queue() is called outside of the context of a
246 * submitted block, its behavior is undefined.
247 *
248 * Passing the result of dispatch_get_main_queue() to this function verifies
249 * that the current block was submitted to the main queue or to a queue
250 * targeting it.
251 * IMPORTANT: this is NOT the same as verifying that the current block is
252 * executing on the main thread.
253 *
254 * The variant dispatch_assert_queue_debug() is compiled out when the
255 * preprocessor macro NDEBUG is defined. (See also assert(3)).
256 *
257 * @param queue
258 * The dispatch queue that the current block is expected to run on.
259 * The result of passing NULL in this parameter is undefined.
260 */
261__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0)
262DISPATCH_EXPORT DISPATCH_NONNULL1
263void
264dispatch_assert_queue(dispatch_queue_t queue);
265
266/*!
267 * @function dispatch_assert_queue_not
268 *
269 * @abstract
270 * Verifies that the current block is not executing on a certain dispatch queue.
271 *
272 * @discussion
273 * This function is the equivalent of dispatch_queue_assert() with the test for
274 * equality inverted. See discussion there.
275 *
276 * The variant dispatch_assert_queue_not_debug() is compiled out when the
277 * preprocessor macro NDEBUG is defined. (See also assert(3)).
278 *
279 * @param queue
280 * The dispatch queue that the current block is expected not to run on.
281 * The result of passing NULL in this parameter is undefined.
282 */
283__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0)
284DISPATCH_EXPORT DISPATCH_NONNULL1
285void
286dispatch_assert_queue_not(dispatch_queue_t queue);
287
288#ifdef NDEBUG
289#define dispatch_assert_queue_debug(q) ((void)0)
290#define dispatch_assert_queue_not_debug(q) ((void)0)
291#else
292#define dispatch_assert_queue_debug(q) dispatch_assert_queue(q)
293#define dispatch_assert_queue_not_debug(q) dispatch_assert_queue_not(q)
294#endif
295
296__END_DECLS
297
298#endif
299