Skip to content

Commit ba8cbe1

Browse files
committed
stdlib: generalise TLS to support Windows
Rename the explicit `pthread` to `thread` to indicate that this is not `pthread` specifically. This allows us to implement the TLS support for Windows using Fibers.
1 parent 74183c4 commit ba8cbe1

File tree

3 files changed

+58
-33
lines changed

3 files changed

+58
-33
lines changed

stdlib/public/SwiftShims/LibcShims.h

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -114,28 +114,28 @@ double _swift_stdlib_squareRoot(double _self) {
114114
// TLS - thread local storage
115115

116116
#if defined(__ANDROID__)
117-
typedef int __swift_pthread_key_t;
117+
typedef int __swift_thread_key_t;
118118
#elif defined(__linux__)
119-
typedef unsigned int __swift_pthread_key_t;
119+
typedef unsigned int __swift_thread_key_t;
120120
#elif defined(__FreeBSD__)
121-
typedef int __swift_pthread_key_t;
121+
typedef int __swift_thread_key_t;
122+
#elif defined(_WIN32)
123+
typedef unsigned long __swift_thread_key_t;
122124
#else
123-
typedef unsigned long __swift_pthread_key_t;
125+
typedef unsigned long __swift_thread_key_t;
124126
#endif
125127

126128
SWIFT_RUNTIME_STDLIB_INTERFACE
127-
int _swift_stdlib_pthread_key_create(
128-
__swift_pthread_key_t * _Nonnull key, void
129-
(* _Nullable destructor)(void * _Nullable )
130-
);
129+
int
130+
_swift_stdlib_thread_key_create(__swift_thread_key_t * _Nonnull key,
131+
void (* _Nullable destructor)(void * _Nullable));
131132

132133
SWIFT_RUNTIME_STDLIB_INTERFACE
133-
void * _Nullable _swift_stdlib_pthread_getspecific(__swift_pthread_key_t key);
134+
void * _Nullable _swift_stdlib_thread_getspecific(__swift_thread_key_t key);
134135

135136
SWIFT_RUNTIME_STDLIB_INTERFACE
136-
int _swift_stdlib_pthread_setspecific(
137-
__swift_pthread_key_t key, const void * _Nullable value
138-
);
137+
int _swift_stdlib_thread_setspecific(__swift_thread_key_t key,
138+
const void * _Nullable value);
139139

140140
// TODO: Remove horrible workaround when importer does Float80 <-> long double.
141141
#if (defined __i386__ || defined __x86_64__) && !defined _MSC_VER

stdlib/public/core/ThreadLocalStorage.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ internal struct _ThreadLocalStorage {
6464
static internal func getPointer()
6565
-> UnsafeMutablePointer<_ThreadLocalStorage>
6666
{
67-
let tlsRawPtr = _swift_stdlib_pthread_getspecific(_tlsKey)
67+
let tlsRawPtr = _swift_stdlib_thread_getspecific(_tlsKey)
6868
if _fastPath(tlsRawPtr != nil) {
6969
return tlsRawPtr._unsafelyUnwrappedUnchecked.assumingMemoryBound(
7070
to: _ThreadLocalStorage.self)
@@ -116,10 +116,10 @@ internal func _destroyTLS(_ ptr: UnsafeMutableRawPointer?) {
116116
}
117117

118118
// Lazily created global key for use with pthread TLS
119-
internal let _tlsKey: __swift_pthread_key_t = {
120-
let sentinelValue = __swift_pthread_key_t.max
121-
var key: __swift_pthread_key_t = sentinelValue
122-
let success = _swift_stdlib_pthread_key_create(&key, _destroyTLS)
119+
internal let _tlsKey: __swift_thread_key_t = {
120+
let sentinelValue = __swift_thread_key_t.max
121+
var key: __swift_thread_key_t = sentinelValue
122+
let success = _swift_stdlib_thread_key_create(&key, _destroyTLS)
123123
_sanityCheck(success == 0, "somehow failed to create TLS key")
124124
_sanityCheck(key != sentinelValue, "Didn't make a new key")
125125
return key
@@ -129,7 +129,7 @@ internal let _tlsKey: __swift_pthread_key_t = {
129129
internal func _initializeThreadLocalStorage()
130130
-> UnsafeMutablePointer<_ThreadLocalStorage>
131131
{
132-
_sanityCheck(_swift_stdlib_pthread_getspecific(_tlsKey) == nil,
132+
_sanityCheck(_swift_stdlib_thread_getspecific(_tlsKey) == nil,
133133
"already initialized")
134134

135135
// Create and initialize one.
@@ -146,7 +146,7 @@ internal func _initializeThreadLocalStorage()
146146
tlsPtr.initialize(
147147
to: _ThreadLocalStorage(_uBreakIterator: newUBreakIterator)
148148
)
149-
let success = _swift_stdlib_pthread_setspecific(_tlsKey, tlsPtr)
149+
let success = _swift_stdlib_thread_setspecific(_tlsKey, tlsPtr)
150150
_sanityCheck(success == 0, "setspecific failed")
151151
return tlsPtr
152152
}

stdlib/public/stubs/LibcShims.cpp

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@
1515
#include <cmath>
1616
#if defined(_WIN32)
1717
#include <io.h>
18+
#define WIN32_LEAN_AND_MEAN
19+
#include <Windows.h>
1820
#else
1921
#include <unistd.h>
20-
#endif
2122
#include <pthread.h>
23+
#endif
2224

2325
#include <stdlib.h>
2426
#include <stdio.h>
@@ -60,7 +62,7 @@ __swift_size_t swift::_swift_stdlib_strlen(const char *s) {
6062

6163
SWIFT_RUNTIME_STDLIB_INTERFACE
6264
__swift_size_t swift::_swift_stdlib_strlen_unsigned(const unsigned char *s) {
63-
return strlen((char *)s);
65+
return strlen(reinterpret_cast<const char *>(s));
6466
}
6567

6668
SWIFT_RUNTIME_STDLIB_INTERFACE
@@ -98,34 +100,57 @@ int swift::_swift_stdlib_close(int fd) {
98100
#endif
99101
}
100102

101-
// Guard compilation on the typedef for __swift_pthread_key_t in LibcShims.h
103+
#if defined(_WIN32)
104+
static_assert(std::is_same<__swift_thread_key_t, DWORD>::value,
105+
"__swift_thread_key_t is not a DWORD");
106+
107+
SWIFT_RUNTIME_STDLIB_INTERFACE
108+
int
109+
swift::_swift_stdlib_thread_key_create(__swift_thread_key_t * _Nonnull key,
110+
void (* _Nullable destructor)(void *)) {
111+
// TODO(compnerd) account for x86 CC violation (__stdcall)
112+
*key = FlsAlloc(reinterpret_cast<PFLS_CALLBACK_FUNCTION>(destructor));
113+
return *key != FLS_OUT_OF_INDEXES;
114+
}
115+
116+
SWIFT_RUNTIME_STDLIB_INTERFACE
117+
void * _Nullable
118+
swift::_swift_stdlib_thread_getspecific(__swift_thread_key_t key) {
119+
return FlsGetValue(key);
120+
}
121+
122+
SWIFT_RUNTIME_STDLIB_INTERFACE
123+
int swift::_swift_stdlib_thread_setspecific(__swift_thread_key_t key,
124+
const void * _Nullable value) {
125+
return FlsSetValue(key, const_cast<void *>(value)) == TRUE;
126+
}
127+
#else
128+
// Guard compilation on the typedef for __swift_thread_key_t in LibcShims.h
102129
// being identical to the platform's pthread_key_t
103-
static_assert(std::is_same<__swift_pthread_key_t, pthread_key_t>::value,
130+
static_assert(std::is_same<__swift_thread_key_t, pthread_key_t>::value,
104131
"This platform's pthread_key_t differs. If you hit this assert, "
105132
"fix __swift_pthread_key_t's typedef in LibcShims.h by adding an "
106133
"#if guard and definition for your platform");
107134

108135
SWIFT_RUNTIME_STDLIB_INTERFACE
109-
int swift::_swift_stdlib_pthread_key_create(
110-
__swift_pthread_key_t * _Nonnull key,
111-
void (* _Nullable destructor)(void *)
112-
) {
136+
int
137+
swift::_swift_stdlib_thread_key_create(__swift_thread_key_t * _Nonnull key,
138+
void (* _Nullable destructor)(void *)) {
113139
return pthread_key_create(key, destructor);
114140
}
115141

116142
SWIFT_RUNTIME_STDLIB_INTERFACE
117-
void * _Nullable swift::_swift_stdlib_pthread_getspecific(
118-
__swift_pthread_key_t key
119-
) {
143+
void * _Nullable
144+
swift::_swift_stdlib_thread_getspecific(__swift_thread_key_t key) {
120145
return pthread_getspecific(key);
121146
}
122147

123148
SWIFT_RUNTIME_STDLIB_INTERFACE
124-
int swift::_swift_stdlib_pthread_setspecific(
125-
__swift_pthread_key_t key, const void * _Nullable value
126-
) {
149+
int swift::_swift_stdlib_thread_setspecific(__swift_thread_key_t key,
150+
const void * _Nullable value) {
127151
return pthread_setspecific(key, value);
128152
}
153+
#endif
129154

130155
#if defined(__APPLE__)
131156
#include <malloc/malloc.h>

0 commit comments

Comments
 (0)