@@ -92,10 +92,76 @@ _dispatch_thread_key_create(const unsigned long *k, void (*d)(void *))
9292 if (!* k || !d ) return ;
9393 dispatch_assert_zero (pthread_key_init_np ((int )* k , d ));
9494}
95+ #elif DISPATCH_USE_THREAD_LOCAL_STORAGE
96+
97+ DISPATCH_TSD_INLINE
98+ static inline void
99+ _dispatch_thread_key_create (pthread_key_t * k , void (* d )(void * ))
100+ {
101+ dispatch_assert_zero (pthread_key_create (k , d ));
102+ }
103+
104+ struct dispatch_tsd {
105+ pid_t tid ;
106+ void * dispatch_queue_key ;
107+ void * dispatch_frame_key ;
108+ void * dispatch_cache_key ;
109+ void * dispatch_context_key ;
110+ void * dispatch_pthread_root_queue_observer_hooks_key ;
111+ void * dispatch_defaultpriority_key ;
112+ #if DISPATCH_INTROSPECTION
113+ void * dispatch_introspection_key ;
114+ #elif DISPATCH_PERF_MON
115+ void * dispatch_bcounter_key ;
116+ #endif
117+ #if DISPATCH_LOCK_USE_SEMAPHORE_FALLBACK
118+ void * dispatch_sema4_key ;
119+ #endif
120+ void * dispatch_priority_key ;
121+ void * dispatch_voucher_key ;
122+ void * dispatch_deferred_items_key ;
123+ };
124+
125+ extern __thread struct dispatch_tsd __dispatch_tsd ;
126+ extern pthread_key_t __dispatch_tsd_key ;
127+ extern void libdispatch_tsd_init (void );
128+ extern void _libdispatch_tsd_cleanup (void * ctx );
129+
130+ DISPATCH_ALWAYS_INLINE
131+ static inline struct dispatch_tsd *
132+ _dispatch_get_tsd_base (void )
133+ {
134+ if (unlikely (__dispatch_tsd .tid == 0 )) {
135+ libdispatch_tsd_init ();
136+ }
137+ OS_COMPILER_CAN_ASSUME (__dispatch_tsd .tid != 0 );
138+ return & __dispatch_tsd ;
139+ }
140+
141+ #define _dispatch_thread_getspecific (key ) \
142+ (_dispatch_get_tsd_base()->key)
143+ #define _dispatch_thread_setspecific (key , value ) \
144+ (void)(_dispatch_get_tsd_base()->key = (value))
145+
146+ #define _dispatch_thread_getspecific_pair (k1 , p1 , k2 , p2 ) \
147+ ( *(p1) = _dispatch_thread_getspecific(k1), \
148+ *(p2) = _dispatch_thread_getspecific(k2) )
149+
150+ #define _dispatch_thread_getspecific_packed_pair (k1 , k2 , p ) \
151+ ( (p)[0] = _dispatch_thread_getspecific(k1), \
152+ (p)[1] = _dispatch_thread_getspecific(k2) )
153+
154+ #define _dispatch_thread_setspecific_pair (k1 , p1 , k2 , p2 ) \
155+ ( _dispatch_thread_setspecific(k1,p1), \
156+ _dispatch_thread_setspecific(k2,p2) )
157+
158+ #define _dispatch_thread_setspecific_packed_pair (k1 , k2 , p ) \
159+ ( _dispatch_thread_setspecific(k1,(p)[0]), \
160+ _dispatch_thread_setspecific(k2,(p)[1]) )
161+
95162#else
96163extern pthread_key_t dispatch_queue_key ;
97164extern pthread_key_t dispatch_frame_key ;
98- extern pthread_key_t dispatch_sema4_key ;
99165extern pthread_key_t dispatch_cache_key ;
100166extern pthread_key_t dispatch_context_key ;
101167extern pthread_key_t dispatch_pthread_root_queue_observer_hooks_key ;
@@ -105,7 +171,8 @@ extern pthread_key_t dispatch_introspection_key;
105171#elif DISPATCH_PERF_MON
106172extern pthread_key_t dispatch_bcounter_key ;
107173#endif
108- extern pthread_key_t dispatch_cache_key ;
174+ extern pthread_key_t dispatch_sema4_key ;
175+ extern pthread_key_t dispatch_priority_key ;
109176extern pthread_key_t dispatch_voucher_key ;
110177extern pthread_key_t dispatch_deferred_items_key ;
111178
@@ -117,6 +184,7 @@ _dispatch_thread_key_create(pthread_key_t *k, void (*d)(void *))
117184}
118185#endif
119186
187+ #ifndef DISPATCH_USE_THREAD_LOCAL_STORAGE
120188DISPATCH_TSD_INLINE
121189static inline void
122190_dispatch_thread_setspecific (pthread_key_t k , void * v )
@@ -210,6 +278,7 @@ _dispatch_thread_setspecific_packed_pair(pthread_key_t k1, pthread_key_t k2,
210278 _dispatch_thread_setspecific (k1 , p [0 ]);
211279 _dispatch_thread_setspecific (k2 , p [1 ]);
212280}
281+ #endif
213282
214283#if TARGET_OS_WIN32
215284#define _dispatch_thread_self () ((uintptr_t)GetCurrentThreadId())
@@ -228,6 +297,8 @@ _dispatch_thread_setspecific_packed_pair(pthread_key_t k1, pthread_key_t k2,
228297#if DISPATCH_USE_DIRECT_TSD
229298#define _dispatch_thread_port () ((mach_port_t)(uintptr_t)\
230299 _dispatch_thread_getspecific(_PTHREAD_TSD_SLOT_MACH_THREAD_SELF))
300+ #elif DISPATCH_USE_THREAD_LOCAL_STORAGE
301+ #define _dispatch_thread_port () ((mach_port_t)(_dispatch_get_tsd_base()->tid))
231302#else
232303#define _dispatch_thread_port () pthread_mach_thread_np(_dispatch_thread_self())
233304#endif
0 commit comments