Tizen 2.1 base
[platform/upstream/gcd.git] / dispatch-1.0 / src / internal.h
1 /*
2  * Copyright (c) 2008-2009 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 #include "config/config.h"
31
32 #define __DISPATCH_BUILDING_DISPATCH__
33 #define __DISPATCH_INDIRECT__
34
35 #include "dispatch/dispatch.h"
36 #include "dispatch/base.h"
37 #include "dispatch/time.h"
38 #include "dispatch/queue.h"
39 #include "dispatch/object.h"
40 #include "dispatch/source.h"
41 #include "dispatch/group.h"
42 #include "dispatch/semaphore.h"
43 #include "dispatch/once.h"
44 #include "dispatch/benchmark.h"
45
46 /* private.h uses #include_next and must be included last to avoid picking
47  * up installed headers. */
48 #include "queue_private.h"
49 #include "source_private.h"
50 #include "private.h"
51
52 #ifndef DISPATCH_NO_LEGACY
53 #include "legacy.h"
54 #endif
55 /* More #includes at EOF (dependent on the contents of internal.h) ... */
56
57 /* The "_debug" library build */
58 #ifndef DISPATCH_DEBUG
59 #define DISPATCH_DEBUG 0
60 #endif
61
62
63 #if HAVE_LIBKERN_OSCROSSENDIAN_H
64 #include <libkern/OSCrossEndian.h>
65 #endif
66 #if HAVE_LIBKERN_OSATOMIC_H
67 #include <libkern/OSAtomic.h>
68 #endif
69 #if HAVE_MACH
70 #include <mach/boolean.h>
71 #include <mach/clock_types.h>
72 #include <mach/clock.h>
73 #include <mach/exception.h>
74 #include <mach/mach.h>
75 #include <mach/mach_error.h>
76 #include <mach/mach_host.h>
77 #include <mach/mach_interface.h>
78 #include <mach/mach_time.h>
79 #include <mach/mach_traps.h>
80 #include <mach/message.h>
81 #include <mach/mig_errors.h>
82 #include <mach/host_info.h>
83 #include <mach/notify.h>
84 #endif /* HAVE_MACH */
85 #if HAVE_MALLOC_MALLOC_H
86 #include <malloc/malloc.h>
87 #endif
88 #include <sys/mount.h>
89 #include <sys/queue.h>
90 #include <sys/stat.h>
91 #if HAVE_SYS_SYSCTL_H
92 #include <sys/sysctl.h>
93 #endif
94 #include <sys/socket.h>
95 #include <sys/time.h>
96 #include <netinet/in.h>
97
98 #ifdef __BLOCKS__
99 #include <Block_private.h>
100 #include <Block.h>
101 #endif /* __BLOCKS__ */
102
103 #include <assert.h>
104 #include <errno.h>
105 #include <fcntl.h>
106 #include <limits.h>
107 #include <search.h>
108 #if USE_POSIX_SEM
109 #include <semaphore.h>
110 #endif
111 #include <signal.h>
112 #include <stdarg.h>
113 #include <stdbool.h>
114 #include <stdint.h>
115 #include <stdio.h>
116 #include <stdlib.h>
117 #include <string.h>
118 #include <syslog.h>
119 #if HAVE_UNISTD_H
120 #include <unistd.h>
121 #endif
122
123 #define DISPATCH_NOINLINE       __attribute__((noinline))
124
125 // workaround 6368156
126 #ifdef NSEC_PER_SEC
127 #undef NSEC_PER_SEC
128 #endif
129 #ifdef USEC_PER_SEC
130 #undef USEC_PER_SEC
131 #endif
132 #ifdef NSEC_PER_USEC
133 #undef NSEC_PER_USEC
134 #endif
135 #define NSEC_PER_SEC 1000000000ull
136 #define USEC_PER_SEC 1000000ull
137 #define NSEC_PER_USEC 1000ull
138
139 /* I wish we had __builtin_expect_range() */
140 #if __GNUC__
141 #define fastpath(x)     ((typeof(x))__builtin_expect((long)(x), ~0l))
142 #define slowpath(x)     ((typeof(x))__builtin_expect((long)(x), 0l))
143 #else
144 #define fastpath(x) (x)
145 #define slowpath(x) (x)
146 #endif
147
148 void _dispatch_bug(size_t line, long val) __attribute__((__noinline__));
149 void _dispatch_abort(size_t line, long val) __attribute__((__noinline__,__noreturn__));
150 void _dispatch_log(const char *msg, ...) __attribute__((__noinline__,__format__(printf,1,2)));
151 void _dispatch_logv(const char *msg, va_list) __attribute__((__noinline__,__format__(printf,1,0)));
152
153 /*
154  * For reporting bugs within libdispatch when using the "_debug" version of the library.
155  */
156 #define dispatch_assert(e)      do {    \
157                 if (__builtin_constant_p(e)) {  \
158                         char __compile_time_assert__[(bool)(e) ? 1 : -1] __attribute__((unused));       \
159                 } else {        \
160                         typeof(e) _e = fastpath(e); /* always eval 'e' */       \
161                         if (DISPATCH_DEBUG && !_e) {    \
162                                 _dispatch_abort(__LINE__, (long)_e);    \
163                         }       \
164                 }       \
165         } while (0)
166 /* A lot of API return zero upon success and not-zero on fail. Let's capture and log the non-zero value */
167 #define dispatch_assert_zero(e) do {    \
168                 if (__builtin_constant_p(e)) {  \
169                         char __compile_time_assert__[(bool)(!(e)) ? 1 : -1] __attribute__((unused));    \
170                 } else {        \
171                         typeof(e) _e = slowpath(e); /* always eval 'e' */       \
172                         if (DISPATCH_DEBUG && _e) {     \
173                                 _dispatch_abort(__LINE__, (long)_e);    \
174                         }       \
175                 }       \
176         } while (0)
177
178 /*
179  * For reporting bugs or impedance mismatches between libdispatch and external subsystems.
180  * These do NOT abort(), and are always compiled into the product.
181  *
182  * In particular, we wrap all system-calls with assume() macros.
183  */
184 #define dispatch_assume(e)      ({      \
185                 typeof(e) _e = fastpath(e); /* always eval 'e' */       \
186                 if (!_e) {      \
187                         if (__builtin_constant_p(e)) {  \
188                                 char __compile_time_assert__[(e) ? 1 : -1];     \
189                                 (void)__compile_time_assert__;  \
190                         }       \
191                         _dispatch_bug(__LINE__, (long)_e);      \
192                 }       \
193                 _e;     \
194         })
195 /* A lot of API return zero upon success and not-zero on fail. Let's capture and log the non-zero value */
196 #define dispatch_assume_zero(e) ({      \
197                 typeof(e) _e = slowpath(e); /* always eval 'e' */       \
198                 if (_e) {       \
199                         if (__builtin_constant_p(e)) {  \
200                                 char __compile_time_assert__[(e) ? -1 : 1];     \
201                                 (void)__compile_time_assert__;  \
202                         }       \
203                         _dispatch_bug(__LINE__, (long)_e);      \
204                 }       \
205                 _e;     \
206         })
207
208 /*
209  * For reporting bugs in clients when using the "_debug" version of the library.
210  */
211 #define dispatch_debug_assert(e, msg, args...)  do {    \
212                 if (__builtin_constant_p(e)) {  \
213                         char __compile_time_assert__[(bool)(e) ? 1 : -1] __attribute__((unused));       \
214                 } else {        \
215                         typeof(e) _e = fastpath(e); /* always eval 'e' */       \
216                         if (DISPATCH_DEBUG && !_e) {    \
217                                 _dispatch_log("%s() 0x%lx: " msg, __func__, (long)_e, ##args);  \
218                                 abort();        \
219                         }       \
220                 }       \
221         } while (0)
222
223 #if __GNUC__
224 #define DO_CAST(x) ((struct dispatch_object_s *)(x)._do)
225 #else
226 #define DO_CAST(x) ((struct dispatch_object_s *)(x))
227 #endif
228
229 #ifdef __BLOCKS__
230 dispatch_block_t _dispatch_Block_copy(dispatch_block_t block);
231 void _dispatch_call_block_and_release(void *block);
232 void _dispatch_call_block_and_release2(void *block, void *ctxt);
233 #endif /* __BLOCKS__ */
234
235 void dummy_function(void);
236 long dummy_function_r0(void);
237
238
239 /* Make sure the debug statments don't get too stale */
240 #define _dispatch_debug(x, args...)     \
241 ({      \
242         if (DISPATCH_DEBUG) {   \
243                 _dispatch_log("libdispatch: %u\t%p\t" x, __LINE__,      \
244                     (void *)_dispatch_thread_self(), ##args);   \
245         }       \
246 })
247
248
249 uint64_t _dispatch_get_nanoseconds(void);
250
251 #ifndef DISPATCH_NO_LEGACY
252 dispatch_source_t
253 _dispatch_source_create2(dispatch_source_t ds,
254         dispatch_source_attr_t attr,
255         void *context,
256         dispatch_source_handler_function_t handler);
257 #endif
258
259 void _dispatch_run_timers(void);
260 // Returns howsoon with updated time value, or NULL if no timers active.
261 struct timespec *_dispatch_get_next_timer_fire(struct timespec *howsoon);
262
263 dispatch_semaphore_t _dispatch_get_thread_semaphore(void);
264 void _dispatch_put_thread_semaphore(dispatch_semaphore_t);
265
266 bool _dispatch_source_testcancel(dispatch_source_t);
267
268 uint64_t _dispatch_timeout(dispatch_time_t when);
269 #if USE_POSIX_SEM
270 struct timespec _dispatch_timeout_ts(dispatch_time_t when);
271 #endif
272
273 __private_extern__ bool _dispatch_safe_fork;
274
275 __private_extern__ struct _dispatch_hw_config_s {
276         uint32_t cc_max_active;
277         uint32_t cc_max_logical;
278         uint32_t cc_max_physical;
279 } _dispatch_hw_config;
280
281 /* #includes dependent on internal.h */
282 #include "object_internal.h"
283 #include "hw_shims.h"
284 #include "os_shims.h"
285 #include "queue_internal.h"
286 #include "semaphore_internal.h"
287 #include "source_internal.h"
288
289 #if USE_APPLE_CRASHREPORTER_INFO
290
291 #if HAVE_MACH
292 // MIG_REPLY_MISMATCH means either:
293 // 1) A signal handler is NOT using async-safe API. See the sigaction(2) man page for more info.
294 // 2) A hand crafted call to mach_msg*() screwed up. Use MIG.
295 #define DISPATCH_VERIFY_MIG(x) do {     \
296                 if ((x) == MIG_REPLY_MISMATCH) {        \
297                         __crashreporter_info__ = "MIG_REPLY_MISMATCH";  \
298                         _dispatch_hardware_crash();     \
299                 }       \
300         } while (0)
301 #endif
302
303 #if defined(__x86_64__) || defined(__i386__)
304 // total hack to ensure that return register of a function is not trashed
305 #define DISPATCH_CRASH(x)       do {    \
306                 asm("mov        %1, %0" : "=m" (__crashreporter_info__) : "c" ("BUG IN LIBDISPATCH: " x));      \
307                 _dispatch_hardware_crash();     \
308         } while (0)
309
310 #define DISPATCH_CLIENT_CRASH(x)        do {    \
311                 asm("mov        %1, %0" : "=m" (__crashreporter_info__) : "c" ("BUG IN CLIENT OF LIBDISPATCH: " x));    \
312                 _dispatch_hardware_crash();     \
313         } while (0)
314
315 #else /* !(defined(__x86_64__) || defined(__i386__)) */
316
317 #define DISPATCH_CRASH(x)       do {    \
318                 __crashreporter_info__ = "BUG IN LIBDISPATCH: " x;      \
319                 _dispatch_hardware_crash();     \
320         } while (0)
321
322 #define DISPATCH_CLIENT_CRASH(x)        do {    \
323                 __crashreporter_info__ = "BUG IN CLIENT OF LIBDISPATCH: " x;    \
324                 _dispatch_hardware_crash();     \
325         } while (0)
326 #endif /* defined(__x86_64__) || defined(__i386__) */
327
328 #else /* !USE_APPLE_CRASHREPORTER_INFO */
329
330 #if HAVE_MACH
331 #define DISPATCH_VERIFY_MIG(x) do {     \
332                 if ((x) == MIG_REPLY_MISMATCH) {        \
333                         _dispatch_hardware_crash();     \
334                 }       \
335         } while (0)
336 #endif
337
338 #define DISPATCH_CRASH(x)               _dispatch_hardware_crash()
339 #define DISPATCH_CLIENT_CRASH(x)        _dispatch_hardware_crash()
340
341 #endif /* USE_APPLE_CRASHREPORTER_INFO */
342
343 #endif /* __DISPATCH_INTERNAL__ */