Skip to content

Commit 7a226d8

Browse files
committed
win32: use native threading APIs instead of pthreads
* use fiber local storage if NO_PTHREADS is defined * use critical sections instead of mutexes Contributing-author: Ben Viglietta <benvi@microsoft.com>
1 parent 2ea1111 commit 7a226d8

File tree

2 files changed

+37
-16
lines changed

2 files changed

+37
-16
lines changed

arc.m

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,36 @@
1313

1414
#ifndef NO_PTHREADS
1515
#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+
}
1742
#endif
1843

44+
arc_tls_key_t ARCThreadKey;
45+
1946
extern void _NSConcreteMallocBlock;
2047
extern void _NSConcreteStackBlock;
2148
extern void _NSConcreteGlobalBlock;
@@ -59,17 +86,13 @@ - (void)release;
5986

6087
static inline struct arc_tls* getARCThreadData(void)
6188
{
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);
6690
if (NULL == tls)
6791
{
6892
tls = calloc(sizeof(struct arc_tls), 1);
69-
pthread_setspecific(ARCThreadKey, tls);
93+
arc_tls_store(ARCThreadKey, tls);
7094
}
7195
return tls;
72-
#endif
7396
}
7497
int count = 0;
7598
int poolCount = 0;
@@ -132,7 +155,7 @@ static void emptyPool(struct arc_tls *tls, id *stop)
132155
//fprintf(stderr, "New insert: %p. Stop: %p\n", tls->pool->insert, stop);
133156
}
134157

135-
static void cleanupPools(struct arc_tls* tls)
158+
static TLS_CALLBACK(cleanupPools)(struct arc_tls* tls)
136159
{
137160
if (tls->returnRetained)
138161
{
@@ -515,9 +538,7 @@ PRIVATE void init_arc(void)
515538
{
516539
weak_ref_initialize(&weakRefs, 128);
517540
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);
521542
}
522543

523544
void* block_load_weak(void *block);

lock.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@
1010
#define BOOL _WINBOOL
1111
# include <windows.h>
1212
#undef BOOL
13-
typedef HANDLE mutex_t;
14-
# define INIT_LOCK(x) x = CreateMutex(NULL, FALSE, NULL)
15-
# define LOCK(x) WaitForSingleObject(*x, INFINITE)
16-
# define UNLOCK(x) ReleaseMutex(*x)
17-
# define DESTROY_LOCK(x) CloseHandle(*x)
13+
typedef CRITICAL_SECTION mutex_t;
14+
# define INIT_LOCK(x) InitializeCriticalSection(&(x))
15+
# define LOCK(x) EnterCriticalSection(x)
16+
# define UNLOCK(x) LeaveCriticalSection(x)
17+
# define DESTROY_LOCK(x) DeleteCriticalSection(x)
1818
#else
1919

2020
# include <pthread.h>

0 commit comments

Comments
 (0)