@@ -30,14 +30,82 @@ extern "C" {
30
30
#include "threading.h"
31
31
32
32
#ifdef JULIA_ENABLE_THREADING
33
+ # if defined(_OS_DARWIN_ )
34
+ // Mac doesn't seem to have static TLS model so the runtime TLS getter
35
+ // registration will only add overhead to TLS access. The `__thread` variables
36
+ // are emulated with `pthread_key_t` so it is actually faster to use it directly.
37
+ static pthread_key_t jl_tls_key ;
38
+
39
+ __attribute__((constructor )) void jl_mac_init_tls (void )
40
+ {
41
+ pthread_key_create (& jl_tls_key , NULL );
42
+ }
43
+
44
+ JL_DLLEXPORT JL_CONST_FUNC jl_tls_states_t * (jl_get_ptls_states )(void )
45
+ {
46
+ void * ptls = pthread_getspecific (jl_tls_key );
47
+ if (__unlikely (!ptls )) {
48
+ ptls = calloc (1 , sizeof (jl_tls_states_t ));
49
+ pthread_setspecific (jl_tls_key , ptls );
50
+ }
51
+ return (jl_tls_states_t * )ptls ;
52
+ }
53
+
54
+ // This is only used after the tls is already initialized on the thread
55
+ static JL_CONST_FUNC jl_tls_states_t * jl_get_ptls_states_fast (void )
56
+ {
57
+ return (jl_tls_states_t * )pthread_getspecific (jl_tls_key );
58
+ }
59
+
60
+ jl_get_ptls_states_func jl_get_ptls_states_getter (void )
61
+ {
62
+ // for codegen
63
+ return & jl_get_ptls_states_fast ;
64
+ }
65
+ # elif defined(_OS_WINDOWS_ )
66
+ // Apparently windows doesn't have a static TLS model (or one that can be
67
+ // reliably used from a shared library) either..... Use `TLSAlloc` instead.
68
+
69
+ static DWORD jl_tls_key ;
70
+
71
+ // Put this here for now. We can move this out later if we find more use for it.
72
+ BOOLEAN WINAPI DllMain (IN HINSTANCE hDllHandle , IN DWORD nReason ,
73
+ IN LPVOID Reserved )
74
+ {
75
+ switch (nReason ) {
76
+ case DLL_PROCESS_ATTACH :
77
+ jl_tls_key = TlsAlloc ();
78
+ assert (jl_tls_key != TLS_OUT_OF_INDEXES );
79
+ // Fall through
80
+ case DLL_THREAD_ATTACH :
81
+ TlsSetValue (jl_tls_key , calloc (1 , sizeof (jl_tls_states_t )));
82
+ break ;
83
+ case DLL_THREAD_DETACH :
84
+ free (TlsGetValue (jl_tls_key ));
85
+ TlsSetValue (jl_tls_key , NULL );
86
+ break ;
87
+ case DLL_PROCESS_DETACH :
88
+ free (TlsGetValue (jl_tls_key ));
89
+ TlsFree (jl_tls_key );
90
+ break ;
91
+ }
92
+ }
93
+
94
+ JL_DLLEXPORT JL_CONST_FUNC jl_tls_states_t * (jl_get_ptls_states )(void )
95
+ {
96
+ return TlsGetValue (jl_tls_key );
97
+ }
98
+
99
+ jl_get_ptls_states_func jl_get_ptls_states_getter (void )
100
+ {
101
+ // for codegen
102
+ return & jl_get_ptls_states ;
103
+ }
104
+ # else
33
105
// fallback provided for embedding
34
106
static JL_CONST_FUNC jl_tls_states_t * jl_get_ptls_states_fallback (void )
35
107
{
36
- # if !defined(_COMPILER_MICROSOFT_ )
37
108
static __thread jl_tls_states_t tls_states ;
38
- # else
39
- static __declspec(thread ) jl_tls_states_t tls_states ;
40
- # endif
41
109
return & tls_states ;
42
110
}
43
111
static jl_tls_states_t * jl_get_ptls_states_init (void );
@@ -78,6 +146,7 @@ jl_get_ptls_states_func jl_get_ptls_states_getter(void)
78
146
// for codegen
79
147
return jl_tls_states_cb ;
80
148
}
149
+ # endif
81
150
#else
82
151
JL_DLLEXPORT jl_tls_states_t jl_tls_states ;
83
152
JL_DLLEXPORT JL_CONST_FUNC jl_tls_states_t * (jl_get_ptls_states )(void )
0 commit comments