]> git.saurik.com Git - apple/libdispatch.git/blob - src/shims/tsd.h
libdispatch-500.1.5.tar.gz
[apple/libdispatch.git] / src / shims / tsd.h
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_SHIMS_TSD__
28 #define __DISPATCH_SHIMS_TSD__
29
30 #if HAVE_PTHREAD_MACHDEP_H
31 #include <pthread_machdep.h>
32 #endif
33
34 #define DISPATCH_TSD_INLINE DISPATCH_ALWAYS_INLINE_NDEBUG
35
36 #if USE_APPLE_TSD_OPTIMIZATIONS && HAVE_PTHREAD_KEY_INIT_NP && \
37 !defined(DISPATCH_USE_DIRECT_TSD)
38 #define DISPATCH_USE_DIRECT_TSD 1
39 #if __has_include(<os/tsd.h>)
40 #include <os/tsd.h>
41 #endif
42 #endif
43
44 #if DISPATCH_USE_DIRECT_TSD
45 static const unsigned long dispatch_queue_key = __PTK_LIBDISPATCH_KEY0;
46 static const unsigned long dispatch_voucher_key = __PTK_LIBDISPATCH_KEY1;
47 static const unsigned long dispatch_cache_key = __PTK_LIBDISPATCH_KEY2;
48 static const unsigned long dispatch_io_key = __PTK_LIBDISPATCH_KEY3;
49 static const unsigned long dispatch_apply_key = __PTK_LIBDISPATCH_KEY4;
50 static const unsigned long dispatch_defaultpriority_key =__PTK_LIBDISPATCH_KEY5;
51 #if DISPATCH_INTROSPECTION
52 static const unsigned long dispatch_introspection_key = __PTK_LIBDISPATCH_KEY6;
53 #elif DISPATCH_PERF_MON
54 static const unsigned long dispatch_bcounter_key = __PTK_LIBDISPATCH_KEY6;
55 #endif
56 #if DISPATCH_USE_OS_SEMAPHORE_CACHE
57 static const unsigned long dispatch_sema4_key = __TSD_SEMAPHORE_CACHE;
58 #else
59 static const unsigned long dispatch_sema4_key = __PTK_LIBDISPATCH_KEY7;
60 #endif
61 static const unsigned long dispatch_pthread_root_queue_observer_hooks_key =
62 __PTK_LIBDISPATCH_KEY8;
63
64 #ifndef __TSD_THREAD_QOS_CLASS
65 #define __TSD_THREAD_QOS_CLASS 4
66 #endif
67 static const unsigned long dispatch_priority_key = __TSD_THREAD_QOS_CLASS;
68
69 DISPATCH_TSD_INLINE
70 static inline void
71 _dispatch_thread_key_create(const unsigned long *k, void (*d)(void *))
72 {
73 if (!*k || !d) return;
74 dispatch_assert_zero(pthread_key_init_np((int)*k, d));
75 }
76 #else
77 extern pthread_key_t dispatch_queue_key;
78 extern pthread_key_t dispatch_voucher_key;
79 #if DISPATCH_USE_OS_SEMAPHORE_CACHE
80 #error "Invalid DISPATCH_USE_OS_SEMAPHORE_CACHE configuration"
81 #else
82 extern pthread_key_t dispatch_sema4_key;
83 #endif
84 extern pthread_key_t dispatch_cache_key;
85 extern pthread_key_t dispatch_io_key;
86 extern pthread_key_t dispatch_apply_key;
87 extern pthread_key_t dispatch_defaultpriority_key;
88 #if DISPATCH_INTROSPECTION
89 extern pthread_key_t dispatch_introspection_key;
90 #elif DISPATCH_PERF_MON
91 extern pthread_key_t dispatch_bcounter_key;
92 #endif
93 exern pthread_key_t dispatch_pthread_root_queue_observer_hooks_key;
94
95 DISPATCH_TSD_INLINE
96 static inline void
97 _dispatch_thread_key_create(pthread_key_t *k, void (*d)(void *))
98 {
99 dispatch_assert_zero(pthread_key_create(k, d));
100 }
101 #endif
102
103 #if DISPATCH_USE_TSD_BASE && !DISPATCH_DEBUG
104 #else // DISPATCH_USE_TSD_BASE
105 DISPATCH_TSD_INLINE
106 static inline void
107 _dispatch_thread_setspecific(pthread_key_t k, void *v)
108 {
109 #if DISPATCH_USE_DIRECT_TSD
110 if (_pthread_has_direct_tsd()) {
111 (void)_pthread_setspecific_direct(k, v);
112 return;
113 }
114 #endif
115 dispatch_assert_zero(pthread_setspecific(k, v));
116 }
117
118 DISPATCH_TSD_INLINE
119 static inline void *
120 _dispatch_thread_getspecific(pthread_key_t k)
121 {
122 #if DISPATCH_USE_DIRECT_TSD
123 if (_pthread_has_direct_tsd()) {
124 return _pthread_getspecific_direct(k);
125 }
126 #endif
127 return pthread_getspecific(k);
128 }
129 #endif // DISPATCH_USE_TSD_BASE
130
131 #if TARGET_OS_WIN32
132 #define _dispatch_thread_self() ((uintptr_t)GetCurrentThreadId())
133 #else
134 #if DISPATCH_USE_DIRECT_TSD
135 #define _dispatch_thread_self() ((uintptr_t)_dispatch_thread_getspecific( \
136 _PTHREAD_TSD_SLOT_PTHREAD_SELF))
137 #else
138 #define _dispatch_thread_self() ((uintptr_t)pthread_self())
139 #endif
140 #endif
141
142 #if TARGET_OS_WIN32
143 #define _dispatch_thread_port() ((mach_port_t)0)
144 #else
145 #if DISPATCH_USE_DIRECT_TSD
146 #define _dispatch_thread_port() ((mach_port_t)_dispatch_thread_getspecific(\
147 _PTHREAD_TSD_SLOT_MACH_THREAD_SELF))
148 #else
149 #define _dispatch_thread_port() (pthread_mach_thread_np(_dispatch_thread_self()))
150 #endif
151 #endif
152
153 DISPATCH_TSD_INLINE DISPATCH_CONST
154 static inline unsigned int
155 _dispatch_cpu_number(void)
156 {
157 #if TARGET_IPHONE_SIMULATOR && IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED < 1090
158 return 0;
159 #elif __has_include(<os/tsd.h>)
160 return _os_cpu_number();
161 #elif defined(__x86_64__) || defined(__i386__)
162 struct { uintptr_t p1, p2; } p;
163 __asm__("sidt %[p]" : [p] "=&m" (p));
164 return (unsigned int)(p.p1 & 0xfff);
165 #else
166 // Not yet implemented.
167 return 0;
168 #endif
169 }
170
171 #undef DISPATCH_TSD_INLINE
172
173 #endif