Skip to content

Commit 9865ea1

Browse files
authored
Fix up a few build failures in environments with constrained concurrency. (#1417)
Fixes a few build failures that have snuck in recently when building with minimal or older concurrency support. ### Checklist: - [x] Code and documentation should follow the style of the [Style Guide](https://github.com/apple/swift-testing/blob/main/Documentation/StyleGuide.md). - [x] If public symbols are renamed or modified, DocC references should be updated.
1 parent fd350e4 commit 9865ea1

File tree

2 files changed

+26
-10
lines changed

2 files changed

+26
-10
lines changed

Sources/Testing/Support/Locked.swift

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
//
1010

1111
internal import _TestingInternals
12+
#if canImport(Synchronization)
1213
private import Synchronization
14+
#endif
1315

1416
/// A type that wraps a value requiring access from a synchronous caller during
1517
/// concurrent execution.
@@ -24,7 +26,7 @@ private import Synchronization
2426
/// This type is not part of the public interface of the testing library.
2527
struct Locked<T> {
2628
/// A type providing storage for the underlying lock and wrapped value.
27-
#if SWT_TARGET_OS_APPLE && canImport(os)
29+
#if SWT_TARGET_OS_APPLE && !SWT_NO_OS_UNFAIR_LOCK
2830
private typealias _Storage = ManagedBuffer<T, os_unfair_lock_s>
2931
#elseif !SWT_FIXED_85448 && (os(Linux) || os(Android))
3032
private final class _Storage: ManagedBuffer<T, pthread_mutex_t> {
@@ -34,14 +36,16 @@ struct Locked<T> {
3436
}
3537
}
3638
}
37-
#else
39+
#elseif canImport(Synchronization)
3840
private final class _Storage {
3941
let mutex: Mutex<T>
4042

4143
init(_ rawValue: consuming sending T) {
4244
mutex = Mutex(rawValue)
4345
}
4446
}
47+
#else
48+
#error("Platform-specific misconfiguration: no mutex or lock type available")
4549
#endif
4650

4751
/// Storage for the underlying lock and wrapped value.
@@ -52,7 +56,7 @@ extension Locked: Sendable where T: Sendable {}
5256

5357
extension Locked: RawRepresentable {
5458
init(rawValue: T) {
55-
#if SWT_TARGET_OS_APPLE && canImport(os)
59+
#if SWT_TARGET_OS_APPLE && !SWT_NO_OS_UNFAIR_LOCK
5660
_storage = .create(minimumCapacity: 1, makingHeaderWith: { _ in rawValue })
5761
_storage.withUnsafeMutablePointerToElements { lock in
5862
lock.initialize(to: .init())
@@ -62,9 +66,11 @@ extension Locked: RawRepresentable {
6266
_storage.withUnsafeMutablePointerToElements { lock in
6367
_ = pthread_mutex_init(lock, nil)
6468
}
65-
#else
69+
#elseif canImport(Synchronization)
6670
nonisolated(unsafe) let rawValue = rawValue
6771
_storage = _Storage(rawValue)
72+
#else
73+
#error("Platform-specific misconfiguration: no mutex or lock type available")
6874
#endif
6975
}
7076

@@ -91,7 +97,7 @@ extension Locked {
9197
/// concurrency tools.
9298
func withLock<R>(_ body: (inout T) throws -> sending R) rethrows -> sending R where R: ~Copyable {
9399
nonisolated(unsafe) let result: R
94-
#if SWT_TARGET_OS_APPLE && canImport(os)
100+
#if SWT_TARGET_OS_APPLE && !SWT_NO_OS_UNFAIR_LOCK
95101
result = try _storage.withUnsafeMutablePointers { rawValue, lock in
96102
os_unfair_lock_lock(lock)
97103
defer {
@@ -107,10 +113,12 @@ extension Locked {
107113
}
108114
return try body(&rawValue.pointee)
109115
}
110-
#else
116+
#elseif canImport(Synchronization)
111117
result = try _storage.mutex.withLock { rawValue in
112118
try body(&rawValue)
113119
}
120+
#else
121+
#error("Platform-specific misconfiguration: no mutex or lock type available")
114122
#endif
115123
return result
116124
}
@@ -130,7 +138,7 @@ extension Locked {
130138
/// concurrency tools.
131139
func withLockIfAvailable<R>(_ body: (inout T) throws -> sending R) rethrows -> sending R? where R: ~Copyable {
132140
nonisolated(unsafe) let result: R?
133-
#if SWT_TARGET_OS_APPLE && canImport(os)
141+
#if SWT_TARGET_OS_APPLE && !SWT_NO_OS_UNFAIR_LOCK
134142
result = try _storage.withUnsafeMutablePointers { rawValue, lock in
135143
guard os_unfair_lock_trylock(lock) else {
136144
return nil
@@ -150,10 +158,12 @@ extension Locked {
150158
}
151159
return try body(&rawValue.pointee)
152160
}
153-
#else
161+
#elseif canImport(Synchronization)
154162
result = try _storage.mutex.withLockIfAvailable { rawValue in
155163
return try body(&rawValue)
156164
}
165+
#else
166+
#error("Platform-specific misconfiguration: no mutex or lock type available")
157167
#endif
158168
return result
159169
}

Sources/Testing/Support/Serializer.swift

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@
1010

1111
private import _TestingInternals
1212

13+
#if !SWT_NO_UNSTRUCTURED_TASKS
1314
/// The number of CPU cores on the current system, or `nil` if that
1415
/// information is not available.
15-
var cpuCoreCount: Int? {
16+
private var _cpuCoreCount: Int? {
1617
#if SWT_TARGET_OS_APPLE || os(Linux) || os(FreeBSD) || os(OpenBSD) || os(Android)
1718
return Int(sysconf(Int32(_SC_NPROCESSORS_CONF)))
1819
#elseif os(Windows)
@@ -26,10 +27,11 @@ var cpuCoreCount: Int? {
2627
return nil
2728
#endif
2829
}
30+
#endif
2931

3032
/// The default parallelization width when parallelized testing is enabled.
3133
var defaultParallelizationWidth: Int {
32-
// cpuCoreCount.map { max(1, $0) * 2 } ?? .max
34+
// _cpuCoreCount.map { max(1, $0) * 2 } ?? .max
3335
.max
3436
}
3537

@@ -45,11 +47,13 @@ final actor Serializer {
4547
/// The maximum number of work items that may run concurrently.
4648
nonisolated let maximumWidth: Int
4749

50+
#if !SWT_NO_UNSTRUCTURED_TASKS
4851
/// The number of scheduled work items, including any currently running.
4952
private var _currentWidth = 0
5053

5154
/// Continuations for any scheduled work items that haven't started yet.
5255
private var _continuations = [CheckedContinuation<Void, Never>]()
56+
#endif
5357

5458
init(maximumWidth: Int = 1) {
5559
precondition(maximumWidth >= 1, "Invalid serializer width \(maximumWidth).")
@@ -65,6 +69,7 @@ final actor Serializer {
6569
///
6670
/// - Throws: Whatever is thrown by `workItem`.
6771
func run<R>(_ workItem: @isolated(any) @Sendable () async throws -> R) async rethrows -> R where R: Sendable {
72+
#if !SWT_NO_UNSTRUCTURED_TASKS
6873
_currentWidth += 1
6974
defer {
7075
// Resume the next scheduled closure.
@@ -86,6 +91,7 @@ final actor Serializer {
8691
_continuations.append(continuation)
8792
}
8893
}
94+
#endif
8995

9096
return try await workItem()
9197
}

0 commit comments

Comments
 (0)