xref: /trueos/lib/libdispatch/src/internal.h (revision d0027a9f69ac2b879f6c228a846fa998dfd60884)
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_INTERNAL__
28 #define __DISPATCH_INTERNAL__
29 
30 #pragma clang diagnostic ignored "-Wcast-qual"
31 #pragma clang diagnostic ignored "-Wpointer-bool-conversion"
32 
33 #include <config/config.h>
34 
35 #define __DISPATCH_BUILDING_DISPATCH__
36 #define __DISPATCH_INDIRECT__
37 
38 #ifdef __APPLE__
39 #include <Availability.h>
40 #include <TargetConditionals.h>
41 #endif
42 
43 
44 #if !defined(DISPATCH_MACH_SPI) && TARGET_OS_MAC
45 #define DISPATCH_MACH_SPI 1
46 #endif
47 #if !defined(OS_VOUCHER_CREATION_SPI) && TARGET_OS_MAC
48 #define OS_VOUCHER_CREATION_SPI 1
49 #endif
50 #if !defined(OS_VOUCHER_ACTIVITY_SPI) && TARGET_OS_MAC
51 #define OS_VOUCHER_ACTIVITY_SPI 1
52 #endif
53 #if !defined(OS_VOUCHER_ACTIVITY_BUFFER_SPI) && TARGET_OS_MAC && \
54 		__has_include(<atm/atm_types.h>)
55 #define OS_VOUCHER_ACTIVITY_BUFFER_SPI 1
56 #endif
57 #if !defined(DISPATCH_LAYOUT_SPI) && TARGET_OS_MAC
58 #define DISPATCH_LAYOUT_SPI 1
59 #endif
60 
61 #if !defined(USE_OBJC) && HAVE_OBJC
62 #define USE_OBJC 1
63 #endif
64 
65 #if USE_OBJC && ((!TARGET_IPHONE_SIMULATOR && defined(__i386__)) || \
66 		(!TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED < 1080))
67 // Disable Objective-C support on platforms with legacy objc runtime
68 #undef USE_OBJC
69 #define USE_OBJC 0
70 #endif
71 
72 #if USE_OBJC
73 #define OS_OBJECT_HAVE_OBJC_SUPPORT 1
74 #if __OBJC__
75 #define OS_OBJECT_USE_OBJC 1
76 #else
77 #define OS_OBJECT_USE_OBJC 0
78 #endif // __OBJC__
79 #else
80 #define OS_OBJECT_HAVE_OBJC_SUPPORT 0
81 #endif // USE_OBJC
82 
83 #include <dispatch/dispatch.h>
84 #include <dispatch/base.h>
85 
86 
87 #include <os/object.h>
88 #include <dispatch/time.h>
89 #include <dispatch/object.h>
90 #include <dispatch/queue.h>
91 #include <dispatch/block.h>
92 #include <dispatch/source.h>
93 #include <dispatch/group.h>
94 #include <dispatch/semaphore.h>
95 #include <dispatch/once.h>
96 #include <dispatch/data.h>
97 #if !TARGET_OS_WIN32
98 #include <dispatch/io.h>
99 #endif
100 
101 #define DISPATCH_STRUCT_DECL(type, name, ...) \
102 	struct type __VA_ARGS__ name
103 
104 // Visual Studio C++ does not support C99 designated initializers.
105 // This means that static declarations should be zero initialized and cannot
106 // be const since we must fill in the values during DLL initialization.
107 #if !TARGET_OS_WIN32
108 #define DISPATCH_STRUCT_INSTANCE(type, name, ...) \
109 struct type name = { \
110 __VA_ARGS__ \
111 }
112 #else
113 #define DISPATCH_STRUCT_INSTANCE(type, name, ...) \
114 struct type name = { 0 }
115 #endif
116 
117 #if !TARGET_OS_WIN32
118 #define DISPATCH_CONST_STRUCT_DECL(type, name, ...) \
119 	const DISPATCH_STRUCT_DECL(type, name, __VA_ARGS__)
120 
121 #define DISPATCH_CONST_STRUCT_INSTANCE(type, name, ...) \
122 	const DISPATCH_STRUCT_INSTANCE(type, name, __VA_ARGS__)
123 #else
124 #define DISPATCH_CONST_STRUCT_DECL(type, name, ...) \
125 	DISPATCH_STRUCT_DECL(type, name, __VA_ARGS__)
126 
127 #define DISPATCH_CONST_STRUCT_INSTANCE(type, name, ...) \
128 	DISPATCH_STRUCT_INSTANCE(type, name, __VA_ARGS__)
129 #endif
130 
131 /* private.h must be included last to avoid picking up installed headers. */
132 #include "object_private.h"
133 #include "queue_private.h"
134 #include "source_private.h"
135 #include "mach_private.h"
136 #include "data_private.h"
137 #if !TARGET_OS_WIN32
138 #include "io_private.h"
139 #endif
140 #include "voucher_private.h"
141 #include "voucher_activity_private.h"
142 #include "layout_private.h"
143 #include "benchmark.h"
144 #include "private.h"
145 
146 /* SPI for Libsystem-internal use */
147 DISPATCH_EXPORT DISPATCH_NOTHROW void libdispatch_init(void);
148 #if !TARGET_OS_WIN32
149 DISPATCH_EXPORT DISPATCH_NOTHROW void dispatch_atfork_prepare(void);
150 DISPATCH_EXPORT DISPATCH_NOTHROW void dispatch_atfork_parent(void);
151 DISPATCH_EXPORT DISPATCH_NOTHROW void dispatch_atfork_child(void);
152 #endif
153 
154 /* More #includes at EOF (dependent on the contents of internal.h) ... */
155 
156 // Abort on uncaught exceptions thrown from client callouts rdar://8577499
157 #if !defined(DISPATCH_USE_CLIENT_CALLOUT)
158 #define DISPATCH_USE_CLIENT_CALLOUT 1
159 #endif
160 
161 /* The "_debug" library build */
162 #ifndef DISPATCH_DEBUG
163 #define DISPATCH_DEBUG 0
164 #endif
165 
166 #ifndef DISPATCH_PROFILE
167 #define DISPATCH_PROFILE 0
168 #endif
169 
170 #if (!TARGET_OS_EMBEDDED || DISPATCH_DEBUG || DISPATCH_PROFILE) && \
171 		!defined(DISPATCH_USE_DTRACE)
172 #define DISPATCH_USE_DTRACE 1
173 #endif
174 
175 #if DISPATCH_USE_DTRACE && (DISPATCH_INTROSPECTION || DISPATCH_DEBUG || \
176 		DISPATCH_PROFILE) && !defined(DISPATCH_USE_DTRACE_INTROSPECTION)
177 #define DISPATCH_USE_DTRACE_INTROSPECTION 1
178 #endif
179 
180 #if HAVE_LIBKERN_OSCROSSENDIAN_H
181 #include <libkern/OSCrossEndian.h>
182 #endif
183 #if HAVE_LIBKERN_OSATOMIC_H
184 #include <libkern/OSAtomic.h>
185 #endif
186 #if HAVE_MACH
187 #include <mach/boolean.h>
188 #include <mach/clock_types.h>
189 #include <mach/clock.h>
190 #include <mach/exception.h>
191 #include <mach/mach.h>
192 #include <mach/mach_error.h>
193 #include <mach/mach_host.h>
194 #include <mach/mach_interface.h>
195 #include <mach/mach_time.h>
196 #include <mach/mach_traps.h>
197 #include <mach/message.h>
198 #include <mach/mig_errors.h>
199 #include <mach/host_special_ports.h>
200 #include <mach/host_info.h>
201 #include <mach/notify.h>
202 #include <mach/mach_vm.h>
203 #include <mach/vm_map.h>
204 #endif /* HAVE_MACH */
205 #if HAVE_MALLOC_MALLOC_H
206 #include <malloc/malloc.h>
207 #endif
208 
209 #include <sys/stat.h>
210 
211 #if !TARGET_OS_WIN32
212 #include <sys/event.h>
213 #include <sys/mount.h>
214 #include <sys/queue.h>
215 #include <sys/sysctl.h>
216 #include <sys/socket.h>
217 #include <sys/time.h>
218 #include <sys/mman.h>
219 #include <netinet/in.h>
220 #else
221 #include "sys_queue.h"
222 #endif
223 
224 #ifdef __BLOCKS__
225 #include <Block_private.h>
226 #include <Block.h>
227 #endif /* __BLOCKS__ */
228 
229 #include <assert.h>
230 #include <errno.h>
231 #if HAVE_FCNTL_H
232 #include <fcntl.h>
233 #endif
234 #include <limits.h>
235 #include <search.h>
236 #if USE_POSIX_SEM
237 #include <semaphore.h>
238 #endif
239 #include <signal.h>
240 #include <stdarg.h>
241 #include <stdbool.h>
242 #include <stdint.h>
243 #include <stdio.h>
244 #include <stdlib.h>
245 #include <string.h>
246 #if HAVE_UNISTD_H
247 #include <unistd.h>
248 #endif
249 
250 #ifndef __has_builtin
251 #define __has_builtin(x) 0
252 #endif
253 #ifndef __has_include
254 #define __has_include(x) 0
255 #endif
256 #ifndef __has_feature
257 #define __has_feature(x) 0
258 #endif
259 #ifndef __has_attribute
260 #define __has_attribute(x) 0
261 #endif
262 
263 #if __GNUC__
264 #define DISPATCH_NOINLINE __attribute__((__noinline__))
265 #define DISPATCH_USED __attribute__((__used__))
266 #define DISPATCH_UNUSED __attribute__((__unused__))
267 #define DISPATCH_WEAK __attribute__((__weak__))
268 #define DISPATCH_OVERLOADABLE __attribute__((__overloadable__))
269 #if DISPATCH_DEBUG
270 #define DISPATCH_ALWAYS_INLINE_NDEBUG
271 #else
272 #define DISPATCH_ALWAYS_INLINE_NDEBUG __attribute__((__always_inline__))
273 #endif
274 #else	/* __GNUC__ */
275 #define DISPATCH_NOINLINE
276 #define DISPATCH_USED
277 #define DISPATCH_UNUSED
278 #define DISPATCH_WEAK
279 #define DISPATCH_ALWAYS_INLINE_NDEBUG
280 #endif	/* __GNUC__ */
281 
282 #define DISPATCH_CONCAT(x,y) DISPATCH_CONCAT1(x,y)
283 #define DISPATCH_CONCAT1(x,y) x ## y
284 
285 // workaround 6368156
286 #ifdef NSEC_PER_SEC
287 #undef NSEC_PER_SEC
288 #endif
289 #ifdef USEC_PER_SEC
290 #undef USEC_PER_SEC
291 #endif
292 #ifdef NSEC_PER_USEC
293 #undef NSEC_PER_USEC
294 #endif
295 #define NSEC_PER_SEC 1000000000ull
296 #define USEC_PER_SEC 1000000ull
297 #define NSEC_PER_USEC 1000ull
298 
299 /* I wish we had __builtin_expect_range() */
300 #if __GNUC__
301 #define fastpath(x) ((typeof(x))__builtin_expect((long)(x), ~0l))
302 #define slowpath(x) ((typeof(x))__builtin_expect((long)(x), 0l))
303 #else
304 #define fastpath(x) (x)
305 #define slowpath(x) (x)
306 #endif // __GNUC__
307 
308 DISPATCH_NOINLINE
309 void _dispatch_bug(size_t line, long val);
310 
311 #if HAVE_MACH
312 DISPATCH_NOINLINE
313 void _dispatch_bug_client(const char* msg);
314 DISPATCH_NOINLINE
315 void _dispatch_bug_mach_client(const char *msg, mach_msg_return_t kr);
316 DISPATCH_NOINLINE
317 void _dispatch_bug_kevent_client(const char* msg, const char* filter,
318 		const char *operation, int err);
319 #endif
320 
321 DISPATCH_NOINLINE DISPATCH_NORETURN
322 void _dispatch_abort(size_t line, long val);
323 
324 #if !defined(DISPATCH_USE_OS_DEBUG_LOG) && DISPATCH_DEBUG
325 #if __has_include(<os/debug_private.h>)
326 #define DISPATCH_USE_OS_DEBUG_LOG 1
327 #include <os/debug_private.h>
328 #endif
329 #endif // DISPATCH_USE_OS_DEBUG_LOG
330 
331 #if !defined(DISPATCH_USE_SIMPLE_ASL) && !DISPATCH_USE_OS_DEBUG_LOG
332 #if __has_include(<_simple.h>)
333 #define DISPATCH_USE_SIMPLE_ASL 1
334 #include <_simple.h>
335 #endif
336 #endif // DISPATCH_USE_SIMPLE_ASL
337 
338 #if !DISPATCH_USE_SIMPLE_ASL && !DISPATCH_USE_OS_DEBUG_LOG && !TARGET_OS_WIN32
339 #include <syslog.h>
340 #endif
341 
342 #if DISPATCH_USE_OS_DEBUG_LOG
343 #define _dispatch_log(msg, ...) os_debug_log("libdispatch", msg, ## __VA_ARGS__)
344 #else
345 DISPATCH_NOINLINE __attribute__((__format__(__printf__,1,2)))
346 void _dispatch_log(const char *msg, ...);
347 #endif // DISPATCH_USE_OS_DEBUG_LOG
348 
349 #define dsnprintf(...) \
350 		({ int _r = snprintf(__VA_ARGS__); _r < 0 ? 0u : (size_t)_r; })
351 
352 /*
353  * For reporting bugs within libdispatch when using the "_debug" version of the
354  * library.
355  */
356 #if __GNUC__
357 #define dispatch_assert(e) do { \
358 		if (__builtin_constant_p(e)) { \
359 			char __compile_time_assert__[(bool)(e) ? 1 : -1] DISPATCH_UNUSED; \
360 		} else { \
361 			typeof(e) _e = fastpath(e); /* always eval 'e' */ \
362 			if (DISPATCH_DEBUG && !_e) { \
363 				_dispatch_abort(__LINE__, (long)_e); \
364 			} \
365 		} \
366 	} while (0)
367 #else
_dispatch_assert(long e,long line)368 static inline void _dispatch_assert(long e, long line) {
369 	if (DISPATCH_DEBUG && !e) _dispatch_abort(line, e);
370 }
371 #define dispatch_assert(e) _dispatch_assert((long)(e), __LINE__)
372 #endif	/* __GNUC__ */
373 
374 #if __GNUC__
375 /*
376  * A lot of API return zero upon success and not-zero on fail. Let's capture
377  * and log the non-zero value
378  */
379 #define dispatch_assert_zero(e) do { \
380 		if (__builtin_constant_p(e)) { \
381 			char __compile_time_assert__[(bool)(e) ? -1 : 1] DISPATCH_UNUSED; \
382 		} else { \
383 			typeof(e) _e = slowpath(e); /* always eval 'e' */ \
384 			if (DISPATCH_DEBUG && _e) { \
385 				_dispatch_abort(__LINE__, (long)_e); \
386 			} \
387 		} \
388 	} while (0)
389 #else
_dispatch_assert_zero(long e,long line)390 static inline void _dispatch_assert_zero(long e, long line) {
391 	if (DISPATCH_DEBUG && e) _dispatch_abort(line, e);
392 }
393 #define dispatch_assert_zero(e) _dispatch_assert((long)(e), __LINE__)
394 #endif	/* __GNUC__ */
395 
396 /*
397  * For reporting bugs or impedance mismatches between libdispatch and external
398  * subsystems. These do NOT abort(), and are always compiled into the product.
399  *
400  * In particular, we wrap all system-calls with assume() macros.
401  */
402 #if __GNUC__
403 #define dispatch_assume(e) ({ \
404 		typeof(e) _e = fastpath(e); /* always eval 'e' */ \
405 		if (!_e) { \
406 			if (__builtin_constant_p(e)) { \
407 				char __compile_time_assert__[(bool)(e) ? 1 : -1]; \
408 				(void)__compile_time_assert__; \
409 			} \
410 			_dispatch_bug(__LINE__, (long)_e); \
411 		} \
412 		_e; \
413 	})
414 #else
_dispatch_assume(long e,long line)415 static inline long _dispatch_assume(long e, long line) {
416 	if (!e) _dispatch_bug(line, e);
417 	return e;
418 }
419 #define dispatch_assume(e) _dispatch_assume((long)(e), __LINE__)
420 #endif	/* __GNUC__ */
421 
422 /*
423  * A lot of API return zero upon success and not-zero on fail. Let's capture
424  * and log the non-zero value
425  */
426 #if __GNUC__
427 #define dispatch_assume_zero(e) ({ \
428 		typeof(e) _e = slowpath(e); /* always eval 'e' */ \
429 		if (_e) { \
430 			if (__builtin_constant_p(e)) { \
431 				char __compile_time_assert__[(bool)(e) ? -1 : 1]; \
432 				(void)__compile_time_assert__; \
433 			} \
434 			_dispatch_bug(__LINE__, (long)_e); \
435 		} \
436 		_e; \
437 	})
438 #else
_dispatch_assume_zero(long e,long line)439 static inline long _dispatch_assume_zero(long e, long line) {
440 	if (e) _dispatch_bug(line, e);
441 	return e;
442 }
443 #define dispatch_assume_zero(e) _dispatch_assume_zero((long)(e), __LINE__)
444 #endif	/* __GNUC__ */
445 
446 /*
447  * For reporting bugs in clients when using the "_debug" version of the library.
448  */
449 #if __GNUC__
450 #define dispatch_debug_assert(e, msg, args...) do { \
451 		if (__builtin_constant_p(e)) { \
452 			char __compile_time_assert__[(bool)(e) ? 1 : -1] DISPATCH_UNUSED; \
453 		} else { \
454 			typeof(e) _e = fastpath(e); /* always eval 'e' */ \
455 			if (DISPATCH_DEBUG && !_e) { \
456 				_dispatch_log("%s() 0x%lx: " msg, __func__, (long)_e, ##args); \
457 				abort(); \
458 			} \
459 		} \
460 	} while (0)
461 #else
462 #define dispatch_debug_assert(e, msg, args...) do { \
463 	long _e = (long)fastpath(e); /* always eval 'e' */ \
464 	if (DISPATCH_DEBUG && !_e) { \
465 		_dispatch_log("%s() 0x%lx: " msg, __FUNCTION__, _e, ##args); \
466 		abort(); \
467 	} \
468 } while (0)
469 #endif	/* __GNUC__ */
470 
471 /* Make sure the debug statments don't get too stale */
472 #define _dispatch_debug(x, args...) do { \
473 	if (DISPATCH_DEBUG) { \
474 		_dispatch_log("%u\t%p\t" x, __LINE__, \
475 				(void *)_dispatch_thread_self(), ##args); \
476 	} \
477 } while (0)
478 
479 #if DISPATCH_DEBUG
480 #if HAVE_MACH
481 DISPATCH_NOINLINE DISPATCH_USED
482 void dispatch_debug_machport(mach_port_t name, const char* str);
483 #endif
484 #endif
485 
486 #if DISPATCH_DEBUG
487 /* This is the private version of the deprecated dispatch_debug() */
488 DISPATCH_NONNULL2 DISPATCH_NOTHROW
489 __attribute__((__format__(printf,2,3)))
490 void
491 _dispatch_object_debug(dispatch_object_t object, const char *message, ...);
492 #else
493 #define _dispatch_object_debug(object, message, ...)
494 #endif // DISPATCH_DEBUG
495 
496 #ifdef __BLOCKS__
497 #define _dispatch_Block_invoke(bb) \
498 		((dispatch_function_t)((struct Block_layout *)bb)->invoke)
499 #if __GNUC__
500 dispatch_block_t _dispatch_Block_copy(dispatch_block_t block);
501 #define _dispatch_Block_copy(x) ((typeof(x))_dispatch_Block_copy(x))
502 #else
503 dispatch_block_t _dispatch_Block_copy(const void *block);
504 #endif
505 void _dispatch_call_block_and_release(void *block);
506 #endif /* __BLOCKS__ */
507 
508 void _dispatch_temporary_resource_shortage(void);
509 void *_dispatch_calloc(size_t num_items, size_t size);
510 void _dispatch_vtable_init(void);
511 char *_dispatch_get_build(void);
512 
513 uint64_t _dispatch_timeout(dispatch_time_t when);
514 
515 extern bool _dispatch_safe_fork, _dispatch_child_of_unsafe_fork;
516 
517 #if !defined(DISPATCH_USE_OS_SEMAPHORE_CACHE) && !(TARGET_IPHONE_SIMULATOR)
518 // rdar://problem/15492045
519 #if __has_include(<os/semaphore_private.h>)
520 #define DISPATCH_USE_OS_SEMAPHORE_CACHE 1
521 #include <os/semaphore_private.h>
522 #endif
523 #endif
524 
525 /* #includes dependent on internal.h */
526 #include "shims.h"
527 
528 // Older Mac OS X and iOS Simulator fallbacks
529 
530 #if HAVE_PTHREAD_WORKQUEUES
531 #ifndef WORKQ_ADDTHREADS_OPTION_OVERCOMMIT
532 #define WORKQ_ADDTHREADS_OPTION_OVERCOMMIT 0x00000001
533 #endif
534 #if TARGET_IPHONE_SIMULATOR && IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED < 1080
535 #ifndef DISPATCH_USE_LEGACY_WORKQUEUE_FALLBACK
536 #define DISPATCH_USE_LEGACY_WORKQUEUE_FALLBACK 1
537 #endif
538 #endif
539 #if !TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED < 1080
540 #undef HAVE_PTHREAD_WORKQUEUE_SETDISPATCH_NP
541 #define HAVE_PTHREAD_WORKQUEUE_SETDISPATCH_NP 0
542 #endif
543 #if TARGET_IPHONE_SIMULATOR && \
544 		IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED < 101000
545 #ifndef DISPATCH_USE_NOQOS_WORKQUEUE_FALLBACK
546 #define DISPATCH_USE_NOQOS_WORKQUEUE_FALLBACK 1
547 #endif
548 #endif
549 #if !TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED < 101000
550 #undef HAVE__PTHREAD_WORKQUEUE_INIT
551 #define HAVE__PTHREAD_WORKQUEUE_INIT 0
552 #endif
553 #endif // HAVE_PTHREAD_WORKQUEUES
554 #if HAVE__PTHREAD_WORKQUEUE_INIT && PTHREAD_WORKQUEUE_SPI_VERSION >= 20140213 \
555 		&& !defined(HAVE_PTHREAD_WORKQUEUE_QOS)
556 #define HAVE_PTHREAD_WORKQUEUE_QOS 1
557 #endif
558 
559 #if HAVE_MACH
560 #if !defined(MACH_NOTIFY_SEND_POSSIBLE) || (TARGET_IPHONE_SIMULATOR && \
561 		IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED < 1070)
562 #undef MACH_NOTIFY_SEND_POSSIBLE
563 #define MACH_NOTIFY_SEND_POSSIBLE MACH_NOTIFY_DEAD_NAME
564 #endif
565 #endif // HAVE_MACH
566 
567 #ifdef EVFILT_MEMORYSTATUS
568 #ifndef DISPATCH_USE_MEMORYSTATUS
569 #define DISPATCH_USE_MEMORYSTATUS 1
570 #endif
571 #endif // EVFILT_MEMORYSTATUS
572 
573 #if defined(EVFILT_VM) && !DISPATCH_USE_MEMORYSTATUS
574 #ifndef DISPATCH_USE_VM_PRESSURE
575 #define DISPATCH_USE_VM_PRESSURE 1
576 #endif
577 #endif // EVFILT_VM
578 
579 #if TARGET_IPHONE_SIMULATOR
580 #undef DISPATCH_USE_MEMORYSTATUS_SOURCE
581 #define DISPATCH_USE_MEMORYSTATUS_SOURCE 0
582 #undef DISPATCH_USE_VM_PRESSURE_SOURCE
583 #define DISPATCH_USE_VM_PRESSURE_SOURCE 0
584 #endif // TARGET_IPHONE_SIMULATOR
585 #if !defined(DISPATCH_USE_MEMORYSTATUS_SOURCE) && DISPATCH_USE_MEMORYSTATUS
586 #define DISPATCH_USE_MEMORYSTATUS_SOURCE 1
587 #elif !defined(DISPATCH_USE_VM_PRESSURE_SOURCE) && DISPATCH_USE_VM_PRESSURE
588 #define DISPATCH_USE_VM_PRESSURE_SOURCE 1
589 #endif
590 
591 #if !defined(NOTE_LEEWAY) || (TARGET_IPHONE_SIMULATOR && \
592 		IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED < 1090)
593 #undef NOTE_LEEWAY
594 #define NOTE_LEEWAY 0
595 #undef NOTE_CRITICAL
596 #define NOTE_CRITICAL 0
597 #undef NOTE_BACKGROUND
598 #define NOTE_BACKGROUND 0
599 #endif // NOTE_LEEWAY
600 
601 #if HAVE_DECL_NOTE_REAP
602 #if defined(NOTE_REAP) && defined(__APPLE__)
603 #undef NOTE_REAP
604 #define NOTE_REAP 0x10000000 // <rdar://problem/13338526>
605 #endif
606 #endif // HAVE_DECL_NOTE_REAP
607 
608 #if defined(F_SETNOSIGPIPE) && defined(F_GETNOSIGPIPE)
609 #if TARGET_IPHONE_SIMULATOR && IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED < 1070
610 #undef DISPATCH_USE_SETNOSIGPIPE
611 #define DISPATCH_USE_SETNOSIGPIPE 0
612 #endif
613 #ifndef DISPATCH_USE_SETNOSIGPIPE
614 #define DISPATCH_USE_SETNOSIGPIPE 1
615 #endif
616 #endif // F_SETNOSIGPIPE
617 
618 #if defined(MACH_SEND_NOIMPORTANCE)
619 #ifndef DISPATCH_USE_CHECKIN_NOIMPORTANCE
620 #define DISPATCH_USE_CHECKIN_NOIMPORTANCE 1 // rdar://problem/16996737
621 #endif
622 #endif // MACH_SEND_NOIMPORTANCE
623 
624 
625 #if HAVE_LIBPROC_INTERNAL_H
626 #include <libproc.h>
627 #include <libproc_internal.h>
628 #if TARGET_IPHONE_SIMULATOR && IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED < 1090
629 #undef DISPATCH_USE_IMPORTANCE_ASSERTION
630 #define DISPATCH_USE_IMPORTANCE_ASSERTION 0
631 #endif
632 #if !TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED < 1090
633 #undef DISPATCH_USE_IMPORTANCE_ASSERTION
634 #define DISPATCH_USE_IMPORTANCE_ASSERTION 0
635 #endif
636 #ifndef DISPATCH_USE_IMPORTANCE_ASSERTION
637 #define DISPATCH_USE_IMPORTANCE_ASSERTION 1
638 #endif
639 #endif // HAVE_LIBPROC_INTERNAL_H
640 
641 #if HAVE_SYS_GUARDED_H
642 #include <sys/guarded.h>
643 #if TARGET_IPHONE_SIMULATOR && IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED < 1090
644 #undef DISPATCH_USE_GUARDED_FD
645 #define DISPATCH_USE_GUARDED_FD 0
646 #endif
647 #ifndef DISPATCH_USE_GUARDED_FD
648 #define DISPATCH_USE_GUARDED_FD 1
649 #endif
650 // change_fdguard_np() requires GUARD_DUP <rdar://problem/11814513>
651 #if DISPATCH_USE_GUARDED_FD && RDAR_11814513
652 #define DISPATCH_USE_GUARDED_FD_CHANGE_FDGUARD 1
653 #endif
654 #endif // HAVE_SYS_GUARDED_H
655 
656 
657 #ifndef MACH_MSGH_BITS_VOUCHER_MASK
658 #define MACH_MSGH_BITS_VOUCHER_MASK	0x001f0000
659 #define	MACH_MSGH_BITS_SET_PORTS(remote, local, voucher)	\
660 	(((remote) & MACH_MSGH_BITS_REMOTE_MASK) | 		\
661 	 (((local) << 8) & MACH_MSGH_BITS_LOCAL_MASK) | 	\
662 	 (((voucher) << 16) & MACH_MSGH_BITS_VOUCHER_MASK))
663 #define	MACH_MSGH_BITS_VOUCHER(bits)				\
664 		(((bits) & MACH_MSGH_BITS_VOUCHER_MASK) >> 16)
665 #define MACH_MSGH_BITS_HAS_VOUCHER(bits)			\
666 	(MACH_MSGH_BITS_VOUCHER(bits) != MACH_MSGH_BITS_ZERO)
667 #define msgh_voucher_port msgh_reserved
668 #define mach_voucher_t mach_port_t
669 #ifndef MACH_VOUCHER_NULL
670 #define MACH_VOUCHER_NULL MACH_PORT_NULL
671 #endif
672 #define MACH_SEND_INVALID_VOUCHER 0x10000005
673 #endif
674 
675 #define _dispatch_hardware_crash() \
676 		__asm__(""); __builtin_trap() // <rdar://problem/17464981>
677 
678 #define _dispatch_set_crash_log_message(msg) \
679 		fprintf(stderr, "%s\n", msg);
680 
681 #if HAVE_MACH
682 // MIG_REPLY_MISMATCH means either:
683 // 1) A signal handler is NOT using async-safe API. See the sigaction(2) man
684 //    page for more info.
685 // 2) A hand crafted call to mach_msg*() screwed up. Use MIG.
686 #define DISPATCH_VERIFY_MIG(x) do { \
687 		if ((x) == MIG_REPLY_MISMATCH) { \
688 			_dispatch_set_crash_log_message("MIG_REPLY_MISMATCH"); \
689 			_dispatch_hardware_crash(); \
690 		} \
691 	} while (0)
692 #endif
693 
694 #define DISPATCH_CRASH(x) do { \
695 		_dispatch_set_crash_log_message("BUG IN LIBDISPATCH: " x); \
696 		_dispatch_hardware_crash(); \
697 	} while (0)
698 
699 #define DISPATCH_CLIENT_CRASH(x) do { \
700 		_dispatch_set_crash_log_message("BUG IN CLIENT OF LIBDISPATCH: " x); \
701 		_dispatch_hardware_crash(); \
702 	} while (0)
703 
704 #define _OS_OBJECT_CLIENT_CRASH(x) do { \
705 		_dispatch_set_crash_log_message("API MISUSE: " x); \
706 		_dispatch_hardware_crash(); \
707 	} while (0)
708 
709 extern int _dispatch_set_qos_class_enabled;
710 #define DISPATCH_NO_VOUCHER ((voucher_t)(void*)~0ul)
711 #define DISPATCH_NO_PRIORITY ((pthread_priority_t)~0ul)
712 #define DISPATCH_PRIORITY_ENFORCE 0x1
713 static inline void _dispatch_adopt_priority_and_replace_voucher(
714 		pthread_priority_t priority, voucher_t voucher, unsigned long flags);
715 #if HAVE_MACH
716 static inline void _dispatch_set_priority_and_mach_voucher(
717 		pthread_priority_t priority, mach_voucher_t kv);
718 mach_port_t _dispatch_get_mach_host_port(void);
719 #endif
720 
721 
722 /* #includes dependent on internal.h */
723 #include "object_internal.h"
724 #include "semaphore_internal.h"
725 #include "introspection_internal.h"
726 #include "queue_internal.h"
727 #include "source_internal.h"
728 #include "voucher_internal.h"
729 #include "data_internal.h"
730 #if !TARGET_OS_WIN32
731 #include "io_internal.h"
732 #endif
733 #include "inline_internal.h"
734 
735 #ifdef __FreeBSD__
736 #define vm_page_size PAGE_SIZE
737 #include <sys/proc.h>
738 #include <mach/mach_port.h>
739 /* XXX need to work out header situation */
740 #define VM_MAKE_TAG(x) 0
741 #define O_SYMLINK       0x200000        /* allow open of a symlink */
742 struct radvisory {
743        off_t   ra_offset;
744        int     ra_count;
745 };
746 #define F_RDADVISE      44              /* Issue an advisory read async with no copy to user */
747 #define KERN_OSVERSION  __FreeBSD_version
748 #define malloc_zone_pressure_relief(a, b)
749 #define mach_vm_round_page round_page
750 #endif
751 
752 #endif /* __DISPATCH_INTERNAL__ */
753