Skip to content

Commit a46f221

Browse files
[wasm] Make Thread APIs available on WASI target
Recent wasi-libc versions include pthreads support for wasip1-threads target and a stub implementation for wasip1 target.
1 parent cf440d8 commit a46f221

File tree

2 files changed

+27
-29
lines changed

2 files changed

+27
-29
lines changed

Sources/CoreFoundation/CFPlatform.c

Lines changed: 12 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1715,43 +1715,37 @@ typedef struct _CFThreadSpecificData {
17151715
__stdcall
17161716
#endif
17171717
static void _CFThreadSpecificDestructor(void *ctx) {
1718-
#if SWIFT_CORELIBS_FOUNDATION_HAS_THREADS
17191718
#if TARGET_OS_WIN32
17201719
_CFThreadSpecificData *data = (_CFThreadSpecificData *)ctx;
17211720
FlsSetValue(data->key, NULL);
17221721
swift_release(data->value);
17231722
free(data);
1724-
#else
1723+
#elif defined(_REENTRANT)
17251724
swift_release(ctx);
17261725
#endif
1727-
#endif
17281726
}
17291727

17301728
_CFThreadSpecificKey _CFThreadSpecificKeyCreate() {
1731-
#if SWIFT_CORELIBS_FOUNDATION_HAS_THREADS
17321729
_CFThreadSpecificKey key;
17331730
#if TARGET_OS_WIN32
17341731
key = FlsAlloc(_CFThreadSpecificDestructor);
1735-
#else
1732+
#elif defined(_REENTRANT)
17361733
pthread_key_create(&key, &_CFThreadSpecificDestructor);
1737-
#endif
1738-
return key;
17391734
#else
1740-
return 0;
1735+
key = 0;
17411736
#endif
1737+
return key;
17421738
}
17431739

17441740
CFTypeRef _Nullable _CFThreadSpecificGet(_CFThreadSpecificKey key) {
1745-
#if SWIFT_CORELIBS_FOUNDATION_HAS_THREADS
17461741
#if TARGET_OS_WIN32
17471742
_CFThreadSpecificData *data = (_CFThreadSpecificData *)FlsGetValue(key);
17481743
if (data == NULL) {
17491744
return NULL;
17501745
}
17511746
return data->value;
1752-
#else
1747+
#elif defined(_REENTRANT)
17531748
return (CFTypeRef)pthread_getspecific(key);
1754-
#endif
17551749
#else
17561750
return NULL;
17571751
#endif
@@ -1761,7 +1755,6 @@ void _CFThreadSpecificSet(_CFThreadSpecificKey key, CFTypeRef _Nullable value) {
17611755
// Intentionally not calling `swift_release` for previous value.
17621756
// OperationQueue uses these API (through NSThreadSpecific), and balances
17631757
// retain count manually.
1764-
#if SWIFT_CORELIBS_FOUNDATION_HAS_THREADS
17651758
#if TARGET_OS_WIN32
17661759
free(FlsGetValue(key));
17671760

@@ -1778,20 +1771,17 @@ void _CFThreadSpecificSet(_CFThreadSpecificKey key, CFTypeRef _Nullable value) {
17781771
}
17791772

17801773
FlsSetValue(key, data);
1781-
#else
1774+
#elif defined(_REENTRANT)
17821775
if (value != NULL) {
17831776
swift_retain((void *)value);
17841777
pthread_setspecific(key, value);
17851778
} else {
17861779
pthread_setspecific(key, NULL);
17871780
}
17881781
#endif
1789-
#else
1790-
#endif
17911782
}
17921783

17931784
_CFThreadRef _CFThreadCreate(const _CFThreadAttributes attrs, void *_Nullable (* _Nonnull startfn)(void *_Nullable), void *_CF_RESTRICT _Nullable context) {
1794-
#if SWIFT_CORELIBS_FOUNDATION_HAS_THREADS
17951785
#if TARGET_OS_WIN32
17961786
DWORD dwCreationFlags = 0;
17971787
DWORD dwStackSize = 0;
@@ -1807,18 +1797,16 @@ _CFThreadRef _CFThreadCreate(const _CFThreadAttributes attrs, void *_Nullable (*
18071797
return (_CFThreadRef)_beginthreadex(NULL, dwStackSize,
18081798
(_beginthreadex_proc_type)startfn,
18091799
context, dwCreationFlags, NULL);
1810-
#else
1800+
#elif defined(_REENTRANT)
18111801
_CFThreadRef thread;
18121802
pthread_create(&thread, &attrs, startfn, context);
18131803
return thread;
1814-
#endif
18151804
#else
18161805
return NULL;
18171806
#endif
18181807
}
18191808

18201809
CF_CROSS_PLATFORM_EXPORT int _CFThreadSetName(_CFThreadRef thread, const char *_Nonnull name) {
1821-
#if SWIFT_CORELIBS_FOUNDATION_HAS_THREADS
18221810
#if TARGET_OS_MAC
18231811
if (pthread_equal(pthread_self(), thread)) {
18241812
return pthread_setname_np(name);
@@ -1848,15 +1836,14 @@ CF_CROSS_PLATFORM_EXPORT int _CFThreadSetName(_CFThreadRef thread, const char *_
18481836
#elif TARGET_OS_BSD
18491837
pthread_set_name_np(thread, name);
18501838
return 0;
1851-
#endif
1852-
#else
1839+
#elif TARGET_OS_WASI
1840+
// No thread naming support in WASI
18531841
return -1;
18541842
#endif
18551843
}
18561844

18571845
// `buf` must be null-terminated
18581846
CF_CROSS_PLATFORM_EXPORT int _CFThreadGetName(char *buf, int length) {
1859-
#if SWIFT_CORELIBS_FOUNDATION_HAS_THREADS
18601847
#if TARGET_OS_MAC
18611848
return pthread_getname_np(pthread_self(), buf, length);
18621849
#elif TARGET_OS_ANDROID
@@ -1902,11 +1889,11 @@ CF_CROSS_PLATFORM_EXPORT int _CFThreadGetName(char *buf, int length) {
19021889
LocalFree(pszThreadDescription);
19031890

19041891
return 0;
1905-
#endif
1906-
return -1;
1907-
#else
1892+
#elif TARGET_OS_WASI
1893+
// No thread naming support in WASI
19081894
return -1;
19091895
#endif
1896+
return -1;
19101897
}
19111898

19121899
CF_EXPORT char **_CFEnviron(void) {

Sources/Foundation/Thread.swift

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
88
//
99

10-
#if canImport(Dispatch)
1110
@_implementationOnly import CoreFoundation
1211
#if os(Windows)
1312
import WinSDK
@@ -19,6 +18,8 @@ import WinSDK
1918
@preconcurrency import Musl
2019
#elseif canImport(Bionic)
2120
@preconcurrency import Bionic
21+
#elseif canImport(WASILibc) && _runtime(_multithreaded)
22+
import wasi_pthread
2223
#endif
2324

2425
// WORKAROUND_SR9811
@@ -124,7 +125,11 @@ open class Thread : NSObject {
124125
}
125126

126127
open class func isMultiThreaded() -> Bool {
128+
#if _runtime(_multithreaded)
127129
return true
130+
#else
131+
return false
132+
#endif
128133
}
129134

130135
@available(*, noasync)
@@ -201,13 +206,18 @@ open class Thread : NSObject {
201206
#endif
202207
}
203208

209+
#if os(WASI)
210+
@available(*, unavailable, message: "exit() is not available on WASI")
211+
#endif
204212
@available(*, noasync)
205213
open class func exit() {
214+
#if !os(WASI)
206215
Thread.current._status = .finished
207216
#if os(Windows)
208217
ExitThread(0)
209218
#else
210219
pthread_exit(nil)
220+
#endif
211221
#endif
212222
}
213223

@@ -248,7 +258,9 @@ open class Thread : NSObject {
248258
#if !os(Windows)
249259
let _ = withUnsafeMutablePointer(to: &_attr) { attr in
250260
pthread_attr_init(attr)
261+
#if !os(WASI) // WASI does not support scheduling contention scope
251262
pthread_attr_setscope(attr, Int32(PTHREAD_SCOPE_SYSTEM))
263+
#endif
252264
pthread_attr_setdetachstate(attr, Int32(PTHREAD_CREATE_DETACHED))
253265
}
254266
#endif
@@ -385,7 +397,7 @@ open class Thread : NSObject {
385397
let maxSupportedStackDepth = 128;
386398
let addrs = UnsafeMutablePointer<UnsafeMutableRawPointer?>.allocate(capacity: maxSupportedStackDepth)
387399
defer { addrs.deallocate() }
388-
#if os(Android) || os(OpenBSD) || canImport(Musl)
400+
#if os(Android) || os(OpenBSD) || canImport(Musl) || os(WASI)
389401
let count = 0
390402
#elseif os(Windows)
391403
let count = RtlCaptureStackBackTrace(0, DWORD(maxSupportedStackDepth),
@@ -408,7 +420,7 @@ open class Thread : NSObject {
408420
}
409421

410422
open class var callStackSymbols: [String] {
411-
#if os(Android) || os(OpenBSD) || canImport(Musl)
423+
#if os(Android) || os(OpenBSD) || canImport(Musl) || os(WASI)
412424
return []
413425
#elseif os(Windows)
414426
let hProcess: HANDLE = GetCurrentProcess()
@@ -478,4 +490,3 @@ extension NSNotification.Name {
478490
public static let NSDidBecomeSingleThreaded = NSNotification.Name(rawValue: "NSDidBecomeSingleThreadedNotification")
479491
public static let NSThreadWillExit = NSNotification.Name(rawValue: "NSThreadWillExitNotification")
480492
}
481-
#endif

0 commit comments

Comments
 (0)