From dfdae8ea992a3234be0bae9733b5fc4977020d34 Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Mon, 1 Sep 2025 17:09:21 +0100 Subject: [PATCH 1/3] Add `enable_wasm_sdk_build: true` to `pull_request.yml` `swift-async-algorithms` should be built for Wasm as one of the officially supported platforms on CI to prevent possible future regressions. --- .github/workflows/pull_request.yml | 4 ++++ Sources/AsyncAlgorithms/Locking.swift | 12 +++++++----- Sources/AsyncSequenceValidation/TaskDriver.swift | 10 ++++++---- .../_CAsyncSequenceValidationSupport.h | 11 +++++++++++ 4 files changed, 28 insertions(+), 9 deletions(-) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 1ed694ad..855cedbb 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -8,6 +8,10 @@ jobs: tests: name: Test uses: swiftlang/github-workflows/.github/workflows/swift_package_test.yml@main + with: + enable_wasm_sdk_build: true + wasm_sdk_build_command: swift build -Xcc -D_WASI_EMULATED_PTHREAD + soundness: name: Soundness uses: swiftlang/github-workflows/.github/workflows/soundness.yml@main diff --git a/Sources/AsyncAlgorithms/Locking.swift b/Sources/AsyncAlgorithms/Locking.swift index d87ef76d..7376c68e 100644 --- a/Sources/AsyncAlgorithms/Locking.swift +++ b/Sources/AsyncAlgorithms/Locking.swift @@ -19,6 +19,8 @@ import Musl import WinSDK #elseif canImport(Bionic) import Bionic +#elseif canImport(wasi_pthread) +import wasi_pthread #else #error("Unsupported platform") #endif @@ -26,7 +28,7 @@ import Bionic internal struct Lock { #if canImport(Darwin) typealias Primitive = os_unfair_lock - #elseif canImport(Glibc) || canImport(Musl) || canImport(Bionic) + #elseif canImport(Glibc) || canImport(Musl) || canImport(Bionic) || canImport(wasi_pthread) typealias Primitive = pthread_mutex_t #elseif canImport(WinSDK) typealias Primitive = SRWLOCK @@ -44,7 +46,7 @@ internal struct Lock { fileprivate static func initialize(_ platformLock: PlatformLock) { #if canImport(Darwin) platformLock.initialize(to: os_unfair_lock()) - #elseif canImport(Glibc) || canImport(Musl) || canImport(Bionic) + #elseif canImport(Glibc) || canImport(Musl) || canImport(Bionic) || canImport(wasi_pthread) let result = pthread_mutex_init(platformLock, nil) precondition(result == 0, "pthread_mutex_init failed") #elseif canImport(WinSDK) @@ -55,7 +57,7 @@ internal struct Lock { } fileprivate static func deinitialize(_ platformLock: PlatformLock) { - #if canImport(Glibc) || canImport(Musl) || canImport(Bionic) + #if canImport(Glibc) || canImport(Musl) || canImport(Bionic) || canImport(wasi_pthread) let result = pthread_mutex_destroy(platformLock) precondition(result == 0, "pthread_mutex_destroy failed") #endif @@ -65,7 +67,7 @@ internal struct Lock { fileprivate static func lock(_ platformLock: PlatformLock) { #if canImport(Darwin) os_unfair_lock_lock(platformLock) - #elseif canImport(Glibc) || canImport(Musl) || canImport(Bionic) + #elseif canImport(Glibc) || canImport(Musl) || canImport(Bionic) || canImport(wasi_pthread) pthread_mutex_lock(platformLock) #elseif canImport(WinSDK) AcquireSRWLockExclusive(platformLock) @@ -77,7 +79,7 @@ internal struct Lock { fileprivate static func unlock(_ platformLock: PlatformLock) { #if canImport(Darwin) os_unfair_lock_unlock(platformLock) - #elseif canImport(Glibc) || canImport(Musl) || canImport(Bionic) + #elseif canImport(Glibc) || canImport(Musl) || canImport(Bionic) || canImport(wasi_pthread) let result = pthread_mutex_unlock(platformLock) precondition(result == 0, "pthread_mutex_unlock failed") #elseif canImport(WinSDK) diff --git a/Sources/AsyncSequenceValidation/TaskDriver.swift b/Sources/AsyncSequenceValidation/TaskDriver.swift index bd7df453..106274cf 100644 --- a/Sources/AsyncSequenceValidation/TaskDriver.swift +++ b/Sources/AsyncSequenceValidation/TaskDriver.swift @@ -19,6 +19,8 @@ import Glibc import Musl #elseif canImport(Bionic) import Bionic +#elseif canImport(wasi_pthread) +import wasi_pthread #elseif canImport(WinSDK) #error("TODO: Port TaskDriver threading to windows") #else @@ -31,7 +33,7 @@ func start_thread(_ raw: UnsafeMutableRawPointer) -> UnsafeMutableRawPointer? { Unmanaged.fromOpaque(raw).takeRetainedValue().run() return nil } -#elseif (canImport(Glibc) && !os(Android)) || canImport(Musl) +#elseif (canImport(Glibc) && !os(Android)) || canImport(Musl) || canImport(wasi_pthread) @available(AsyncAlgorithms 1.0, *) func start_thread(_ raw: UnsafeMutableRawPointer?) -> UnsafeMutableRawPointer? { Unmanaged.fromOpaque(raw!).takeRetainedValue().run() @@ -51,7 +53,7 @@ func start_thread(_ raw: UnsafeMutableRawPointer) -> UnsafeMutableRawPointer { final class TaskDriver { let work: (TaskDriver) -> Void let queue: WorkQueue - #if canImport(Darwin) + #if canImport(Darwin) || canImport(wasi_pthread) var thread: pthread_t? #elseif canImport(Glibc) || canImport(Musl) || canImport(Bionic) var thread = pthread_t() @@ -65,7 +67,7 @@ final class TaskDriver { } func start() { - #if canImport(Darwin) || canImport(Glibc) || canImport(Musl) || canImport(Bionic) + #if canImport(Darwin) || canImport(Glibc) || canImport(Musl) || canImport(Bionic) || canImport(wasi_pthread) pthread_create( &thread, nil, @@ -85,7 +87,7 @@ final class TaskDriver { } func join() { - #if canImport(Darwin) + #if canImport(Darwin) || canImport(wasi_pthread) pthread_join(thread!, nil) #elseif canImport(Glibc) || canImport(Musl) || canImport(Bionic) pthread_join(thread, nil) diff --git a/Sources/_CAsyncSequenceValidationSupport/_CAsyncSequenceValidationSupport.h b/Sources/_CAsyncSequenceValidationSupport/_CAsyncSequenceValidationSupport.h index 9780327c..b50ef5cf 100644 --- a/Sources/_CAsyncSequenceValidationSupport/_CAsyncSequenceValidationSupport.h +++ b/Sources/_CAsyncSequenceValidationSupport/_CAsyncSequenceValidationSupport.h @@ -246,3 +246,14 @@ SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift) void (* _Nullable swift_task_enqueueGlobal_hook)( JobRef _Nonnull job, swift_task_enqueueGlobal_original _Nonnull original); +// Workaround for `macro 'pthread_join' unavailable: function like macros not supported` +#if defined(__wasi__) + +#include + +int swift_async_sequencey_pthread_join(pthread_t thread, void **value_ptr) { + return pthread_join(thread, value_ptr); +} + +#endif + From dbf64031d96231b9a394d4397d4d255949f6da21 Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Mon, 1 Sep 2025 17:35:29 +0100 Subject: [PATCH 2/3] Clean up unused function --- .../_CAsyncSequenceValidationSupport.h | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/Sources/_CAsyncSequenceValidationSupport/_CAsyncSequenceValidationSupport.h b/Sources/_CAsyncSequenceValidationSupport/_CAsyncSequenceValidationSupport.h index b50ef5cf..734fa8da 100644 --- a/Sources/_CAsyncSequenceValidationSupport/_CAsyncSequenceValidationSupport.h +++ b/Sources/_CAsyncSequenceValidationSupport/_CAsyncSequenceValidationSupport.h @@ -245,15 +245,3 @@ typedef SWIFT_CC(swift) void (*swift_task_enqueueGlobal_original)(JobRef _Nonnul SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift) void (* _Nullable swift_task_enqueueGlobal_hook)( JobRef _Nonnull job, swift_task_enqueueGlobal_original _Nonnull original); - -// Workaround for `macro 'pthread_join' unavailable: function like macros not supported` -#if defined(__wasi__) - -#include - -int swift_async_sequencey_pthread_join(pthread_t thread, void **value_ptr) { - return pthread_join(thread, value_ptr); -} - -#endif - From bb1ce6af83036026c5c14193ba173133ad5c0748 Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Mon, 1 Sep 2025 17:36:38 +0100 Subject: [PATCH 3/3] Add missing trailing newline --- .../_CAsyncSequenceValidationSupport.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Sources/_CAsyncSequenceValidationSupport/_CAsyncSequenceValidationSupport.h b/Sources/_CAsyncSequenceValidationSupport/_CAsyncSequenceValidationSupport.h index 734fa8da..9780327c 100644 --- a/Sources/_CAsyncSequenceValidationSupport/_CAsyncSequenceValidationSupport.h +++ b/Sources/_CAsyncSequenceValidationSupport/_CAsyncSequenceValidationSupport.h @@ -245,3 +245,4 @@ typedef SWIFT_CC(swift) void (*swift_task_enqueueGlobal_original)(JobRef _Nonnul SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift) void (* _Nullable swift_task_enqueueGlobal_hook)( JobRef _Nonnull job, swift_task_enqueueGlobal_original _Nonnull original); +