2  * Copyright (c) 2008-2011 Apple Inc. All rights reserved. 
   4  * @APPLE_APACHE_LICENSE_HEADER_START@ 
   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 
  10  *     http://www.apache.org/licenses/LICENSE-2.0 
  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. 
  18  * @APPLE_APACHE_LICENSE_HEADER_END@ 
  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. 
  27 #ifndef __DISPATCH_INTERNAL__ 
  28 #define __DISPATCH_INTERNAL__ 
  30 #include <config/config.h> 
  32 #define __DISPATCH_BUILDING_DISPATCH__ 
  33 #define __DISPATCH_INDIRECT__ 
  36 #include <dispatch/dispatch.h> 
  37 #include <dispatch/base.h> 
  40 #include <dispatch/time.h> 
  41 #include <dispatch/queue.h> 
  42 #include <dispatch/object.h> 
  43 #include <dispatch/source.h> 
  44 #include <dispatch/group.h> 
  45 #include <dispatch/semaphore.h> 
  46 #include <dispatch/once.h> 
  47 #include <dispatch/data.h> 
  48 #include <dispatch/io.h> 
  50 /* private.h uses #include_next and must be included last to avoid picking 
  51  * up installed headers. */ 
  52 #include "queue_private.h" 
  53 #include "source_private.h" 
  54 #include "benchmark.h" 
  57 /* More #includes at EOF (dependent on the contents of internal.h) ... */ 
  59 /* The "_debug" library build */ 
  60 #ifndef DISPATCH_DEBUG 
  61 #define DISPATCH_DEBUG 0 
  64 #ifndef DISPATCH_PROFILE 
  65 #define DISPATCH_PROFILE 0 
  68 #if DISPATCH_DEBUG && !defined(DISPATCH_USE_CLIENT_CALLOUT) 
  69 #define DISPATCH_USE_CLIENT_CALLOUT 1 
  72 #if (DISPATCH_DEBUG || DISPATCH_PROFILE) && !defined(DISPATCH_USE_DTRACE) 
  73 #define DISPATCH_USE_DTRACE 1 
  76 #if HAVE_LIBKERN_OSCROSSENDIAN_H 
  77 #include <libkern/OSCrossEndian.h> 
  79 #if HAVE_LIBKERN_OSATOMIC_H 
  80 #include <libkern/OSAtomic.h> 
  83 #include <mach/boolean.h> 
  84 #include <mach/clock_types.h> 
  85 #include <mach/clock.h> 
  86 #include <mach/exception.h> 
  87 #include <mach/mach.h> 
  88 #include <mach/mach_error.h> 
  89 #include <mach/mach_host.h> 
  90 #include <mach/mach_interface.h> 
  91 #include <mach/mach_time.h> 
  92 #include <mach/mach_traps.h> 
  93 #include <mach/message.h> 
  94 #include <mach/mig_errors.h> 
  95 #include <mach/host_info.h> 
  96 #include <mach/notify.h> 
  97 #endif /* HAVE_MACH */ 
  98 #if HAVE_MALLOC_MALLOC_H 
  99 #include <malloc/malloc.h> 
 101 #include <sys/event.h> 
 102 #include <sys/mount.h> 
 103 #include <sys/queue.h> 
 104 #include <sys/stat.h> 
 105 #include <sys/sysctl.h> 
 106 #include <sys/socket.h> 
 107 #include <sys/time.h> 
 108 #include <netinet/in.h> 
 111 #include <Block_private.h> 
 113 #endif /* __BLOCKS__ */ 
 121 #include <semaphore.h> 
 135 #ifndef __has_builtin 
 136 #define __has_builtin(x) 0 
 138 #ifndef __has_include 
 139 #define __has_include(x) 0 
 141 #ifndef __has_feature 
 142 #define __has_feature(x) 0 
 144 #ifndef __has_attribute 
 145 #define __has_attribute(x) 0 
 148 #define DISPATCH_NOINLINE __attribute__((__noinline__)) 
 149 #define DISPATCH_USED __attribute__((__used__)) 
 150 #define DISPATCH_UNUSED __attribute__((__unused__)) 
 151 #define DISPATCH_WEAK __attribute__((__weak__)) 
 153 #define DISPATCH_ALWAYS_INLINE_NDEBUG 
 155 #define DISPATCH_ALWAYS_INLINE_NDEBUG __attribute__((__always_inline__)) 
 158 // workaround 6368156 
 168 #define NSEC_PER_SEC 1000000000ull 
 169 #define USEC_PER_SEC 1000000ull 
 170 #define NSEC_PER_USEC 1000ull 
 172 /* I wish we had __builtin_expect_range() */ 
 173 #define fastpath(x) ((typeof(x))__builtin_expect((long)(x), ~0l)) 
 174 #define slowpath(x) ((typeof(x))__builtin_expect((long)(x), 0l)) 
 177 void _dispatch_bug(size_t line
, long val
); 
 179 void _dispatch_bug_mach_client(const char *msg
, mach_msg_return_t kr
); 
 180 DISPATCH_NOINLINE DISPATCH_NORETURN
 
 181 void _dispatch_abort(size_t line
, long val
); 
 182 DISPATCH_NOINLINE 
__attribute__((__format__(printf
,1,2))) 
 183 void _dispatch_log(const char *msg
, ...); 
 184 DISPATCH_NOINLINE 
__attribute__((__format__(printf
,1,0))) 
 185 void _dispatch_logv(const char *msg
, va_list); 
 188  * For reporting bugs within libdispatch when using the "_debug" version of the 
 191 #define dispatch_assert(e) do { \ 
 192                 if (__builtin_constant_p(e)) { \ 
 193                         char __compile_time_assert__[(bool)(e) ? 1 : -1] DISPATCH_UNUSED; \ 
 195                         typeof(e) _e = fastpath(e); /* always eval 'e' */ \ 
 196                         if (DISPATCH_DEBUG && !_e) { \ 
 197                                 _dispatch_abort(__LINE__, (long)_e); \ 
 202  * A lot of API return zero upon success and not-zero on fail. Let's capture 
 203  * and log the non-zero value 
 205 #define dispatch_assert_zero(e) do { \ 
 206                 if (__builtin_constant_p(e)) { \ 
 207                         char __compile_time_assert__[(bool)(e) ? -1 : 1] DISPATCH_UNUSED; \ 
 209                         typeof(e) _e = slowpath(e); /* always eval 'e' */ \ 
 210                         if (DISPATCH_DEBUG && _e) { \ 
 211                                 _dispatch_abort(__LINE__, (long)_e); \ 
 217  * For reporting bugs or impedance mismatches between libdispatch and external 
 218  * subsystems. These do NOT abort(), and are always compiled into the product. 
 220  * In particular, we wrap all system-calls with assume() macros. 
 222 #define dispatch_assume(e) ({ \ 
 223                 typeof(e) _e = fastpath(e); /* always eval 'e' */ \ 
 225                         if (__builtin_constant_p(e)) { \ 
 226                                 char __compile_time_assert__[(bool)(e) ? 1 : -1]; \ 
 227                                 (void)__compile_time_assert__; \ 
 229                         _dispatch_bug(__LINE__, (long)_e); \ 
 234  * A lot of API return zero upon success and not-zero on fail. Let's capture 
 235  * and log the non-zero value 
 237 #define dispatch_assume_zero(e) ({ \ 
 238                 typeof(e) _e = slowpath(e); /* always eval 'e' */ \ 
 240                         if (__builtin_constant_p(e)) { \ 
 241                                 char __compile_time_assert__[(bool)(e) ? -1 : 1]; \ 
 242                                 (void)__compile_time_assert__; \ 
 244                         _dispatch_bug(__LINE__, (long)_e); \ 
 250  * For reporting bugs in clients when using the "_debug" version of the library. 
 252 #define dispatch_debug_assert(e, msg, args...) do { \ 
 253                 if (__builtin_constant_p(e)) { \ 
 254                         char __compile_time_assert__[(bool)(e) ? 1 : -1] DISPATCH_UNUSED; \ 
 256                         typeof(e) _e = fastpath(e); /* always eval 'e' */ \ 
 257                         if (DISPATCH_DEBUG && !_e) { \ 
 258                                 _dispatch_log("%s() 0x%lx: " msg, __func__, (long)_e, ##args); \ 
 264 /* Make sure the debug statments don't get too stale */ 
 265 #define _dispatch_debug(x, args...) \ 
 267         if (DISPATCH_DEBUG) { \ 
 268                 _dispatch_log("libdispatch: %u\t%p\t" x, __LINE__, \ 
 269                                 (void *)_dispatch_thread_self(), ##args); \ 
 275 DISPATCH_NOINLINE DISPATCH_USED
 
 276 void dispatch_debug_machport(mach_port_t name
, const char* str
); 
 278 DISPATCH_NOINLINE DISPATCH_USED
 
 279 void dispatch_debug_kevents(struct kevent
* kev
, size_t count
, const char* str
); 
 282 dispatch_debug_kevents(struct kevent
* kev DISPATCH_UNUSED
, 
 283                 size_t count DISPATCH_UNUSED
, 
 284                 const char* str DISPATCH_UNUSED
) {} 
 287 #if DISPATCH_USE_CLIENT_CALLOUT 
 289 DISPATCH_NOTHROW 
void 
 290 _dispatch_client_callout(void *ctxt
, dispatch_function_t f
); 
 291 DISPATCH_NOTHROW 
void 
 292 _dispatch_client_callout2(void *ctxt
, size_t i
, void (*f
)(void *, size_t)); 
 296 DISPATCH_ALWAYS_INLINE
 
 298 _dispatch_client_callout(void *ctxt
, dispatch_function_t f
) 
 303 DISPATCH_ALWAYS_INLINE
 
 305 _dispatch_client_callout2(void *ctxt
, size_t i
, void (*f
)(void *, size_t)) 
 313 DISPATCH_ALWAYS_INLINE
 
 315 _dispatch_client_callout_block(dispatch_block_t b
) 
 317         struct Block_basic 
*bb 
= (void*)b
; 
 318         return _dispatch_client_callout(b
, (dispatch_function_t
)bb
->Block_invoke
); 
 321 dispatch_block_t 
_dispatch_Block_copy(dispatch_block_t block
); 
 322 #define _dispatch_Block_copy(x) ((typeof(x))_dispatch_Block_copy(x)) 
 323 void _dispatch_call_block_and_release(void *block
); 
 324 #endif /* __BLOCKS__ */ 
 326 void dummy_function(void); 
 327 long dummy_function_r0(void); 
 329 void _dispatch_source_drain_kevent(struct kevent 
*); 
 331 long _dispatch_update_kq(const struct kevent 
*); 
 332 void _dispatch_run_timers(void); 
 333 // Returns howsoon with updated time value, or NULL if no timers active. 
 334 struct timespec 
*_dispatch_get_next_timer_fire(struct timespec 
*howsoon
); 
 336 bool _dispatch_source_testcancel(dispatch_source_t
); 
 338 uint64_t _dispatch_timeout(dispatch_time_t when
); 
 340 extern bool _dispatch_safe_fork
; 
 342 extern struct _dispatch_hw_config_s 
{ 
 343         uint32_t cc_max_active
; 
 344         uint32_t cc_max_logical
; 
 345         uint32_t cc_max_physical
; 
 346 } _dispatch_hw_config
; 
 348 /* #includes dependent on internal.h */ 
 350 #include "object_internal.h" 
 351 #include "queue_internal.h" 
 352 #include "semaphore_internal.h" 
 353 #include "source_internal.h" 
 354 #include "data_internal.h" 
 355 #include "io_internal.h" 
 358 // SnowLeopard and iOS Simulator fallbacks 
 360 #if HAVE_PTHREAD_WORKQUEUES 
 361 #if !defined(WORKQ_BG_PRIOQUEUE) || \ 
 362                 (TARGET_IPHONE_SIMULATOR && __MAC_OS_X_VERSION_MIN_REQUIRED < 1070) 
 363 #undef WORKQ_BG_PRIOQUEUE 
 364 #define WORKQ_BG_PRIOQUEUE WORKQ_LOW_PRIOQUEUE 
 366 #endif // HAVE_PTHREAD_WORKQUEUES 
 369 #if !defined(MACH_NOTIFY_SEND_POSSIBLE) || \ 
 370                 (TARGET_IPHONE_SIMULATOR && __MAC_OS_X_VERSION_MIN_REQUIRED < 1070) 
 371 #undef MACH_NOTIFY_SEND_POSSIBLE 
 372 #define MACH_NOTIFY_SEND_POSSIBLE MACH_NOTIFY_DEAD_NAME 
 377 #if TARGET_IPHONE_SIMULATOR && __MAC_OS_X_VERSION_MIN_REQUIRED < 1070 
 378 #undef DISPATCH_USE_MALLOC_VM_PRESSURE_SOURCE 
 379 #define DISPATCH_USE_MALLOC_VM_PRESSURE_SOURCE 0 
 381 #ifndef DISPATCH_USE_VM_PRESSURE 
 382 #define DISPATCH_USE_VM_PRESSURE 1 
 384 #ifndef DISPATCH_USE_MALLOC_VM_PRESSURE_SOURCE 
 385 #define DISPATCH_USE_MALLOC_VM_PRESSURE_SOURCE 1 
 389 #if defined(F_SETNOSIGPIPE) && defined(F_GETNOSIGPIPE) 
 390 #if TARGET_IPHONE_SIMULATOR && __MAC_OS_X_VERSION_MIN_REQUIRED < 1070 
 391 #undef DISPATCH_USE_SETNOSIGPIPE 
 392 #define DISPATCH_USE_SETNOSIGPIPE 0 
 394 #ifndef DISPATCH_USE_SETNOSIGPIPE 
 395 #define DISPATCH_USE_SETNOSIGPIPE 1 
 397 #endif // F_SETNOSIGPIPE 
 400 #define _dispatch_set_crash_log_message(x) 
 403 // MIG_REPLY_MISMATCH means either: 
 404 // 1) A signal handler is NOT using async-safe API. See the sigaction(2) man 
 405 //    page for more info. 
 406 // 2) A hand crafted call to mach_msg*() screwed up. Use MIG. 
 407 #define DISPATCH_VERIFY_MIG(x) do { \ 
 408                 if ((x) == MIG_REPLY_MISMATCH) { \ 
 409                         _dispatch_set_crash_log_message("MIG_REPLY_MISMATCH"); \ 
 410                         _dispatch_hardware_crash(); \ 
 415 #define DISPATCH_CRASH(x) do { \ 
 416                 _dispatch_set_crash_log_message("BUG IN LIBDISPATCH: " x); \ 
 417                 _dispatch_hardware_crash(); \ 
 420 #define DISPATCH_CLIENT_CRASH(x) do { \ 
 421                 _dispatch_set_crash_log_message("BUG IN CLIENT OF LIBDISPATCH: " x); \ 
 422                 _dispatch_hardware_crash(); \ 
 425 #endif /* __DISPATCH_INTERNAL__ */