|
13 | 13 |
|
14 | 14 | #ifndef NO_PTHREADS
|
15 | 15 | #include <pthread.h>
|
16 |
| -pthread_key_t ARCThreadKey; |
| 16 | +typedef pthread_key_t arc_tls_key_t; |
| 17 | +#define arc_tls_store pthread_setspecific |
| 18 | +#define arc_tls_load pthread_getspecific |
| 19 | +#define TLS_CALLBACK(name) void name |
| 20 | + |
| 21 | +static inline pthread_key_t arc_tls_key_create(void(*cleanupFunction)(void*)) |
| 22 | +{ |
| 23 | + pthread_key_t key; |
| 24 | + pthread_key_create(&key, cleanupFunction); |
| 25 | + return key; |
| 26 | +} |
| 27 | +#else // if defined(NO_PTHREADS) |
| 28 | +// We're using the Fiber-Local Storage APIs on Windows |
| 29 | +// because the TLS APIs won't pass app certification. |
| 30 | +// Additionally, the FLS API surface is 1:1 mapped to |
| 31 | +// the TLS API surface when fibers are not in use. |
| 32 | +#include <Windows.h> |
| 33 | +typedef DWORD arc_tls_key_t; |
| 34 | +#define arc_tls_store FlsSetValue |
| 35 | +#define arc_tls_load FlsGetValue |
| 36 | +#define TLS_CALLBACK(name) void WINAPI name |
| 37 | + |
| 38 | +static inline DWORD arc_tls_key_create(void WINAPI(*cleanupFunction)(void*)) |
| 39 | +{ |
| 40 | + return FlsAlloc(cleanupFunction); |
| 41 | +} |
17 | 42 | #endif
|
18 | 43 |
|
| 44 | +arc_tls_key_t ARCThreadKey; |
| 45 | + |
19 | 46 | extern void _NSConcreteMallocBlock;
|
20 | 47 | extern void _NSConcreteStackBlock;
|
21 | 48 | extern void _NSConcreteGlobalBlock;
|
@@ -59,17 +86,13 @@ - (void)release;
|
59 | 86 |
|
60 | 87 | static inline struct arc_tls* getARCThreadData(void)
|
61 | 88 | {
|
62 |
| -#ifdef NO_PTHREADS |
63 |
| - return NULL; |
64 |
| -#else |
65 |
| - struct arc_tls *tls = pthread_getspecific(ARCThreadKey); |
| 89 | + struct arc_tls *tls = arc_tls_load(ARCThreadKey); |
66 | 90 | if (NULL == tls)
|
67 | 91 | {
|
68 | 92 | tls = calloc(sizeof(struct arc_tls), 1);
|
69 |
| - pthread_setspecific(ARCThreadKey, tls); |
| 93 | + arc_tls_store(ARCThreadKey, tls); |
70 | 94 | }
|
71 | 95 | return tls;
|
72 |
| -#endif |
73 | 96 | }
|
74 | 97 | int count = 0;
|
75 | 98 | int poolCount = 0;
|
@@ -132,7 +155,7 @@ static void emptyPool(struct arc_tls *tls, id *stop)
|
132 | 155 | //fprintf(stderr, "New insert: %p. Stop: %p\n", tls->pool->insert, stop);
|
133 | 156 | }
|
134 | 157 |
|
135 |
| -static void cleanupPools(struct arc_tls* tls) |
| 158 | +static TLS_CALLBACK(cleanupPools)(struct arc_tls* tls) |
136 | 159 | {
|
137 | 160 | if (tls->returnRetained)
|
138 | 161 | {
|
@@ -515,9 +538,7 @@ PRIVATE void init_arc(void)
|
515 | 538 | {
|
516 | 539 | weak_ref_initialize(&weakRefs, 128);
|
517 | 540 | INIT_LOCK(weakRefLock);
|
518 |
| -#ifndef NO_PTHREADS |
519 |
| - pthread_key_create(&ARCThreadKey, (void(*)(void*))cleanupPools); |
520 |
| -#endif |
| 541 | + ARCThreadKey = arc_tls_key_create((void(*)(void*))cleanupPools); |
521 | 542 | }
|
522 | 543 |
|
523 | 544 | void* block_load_weak(void *block);
|
|
0 commit comments