Merge pull request #85312 from al45tair/concurrency-6.3-not-6.2

[Concurrency] Change all of the StdlibDeploymentTarget 6.2s to 6.3.
This commit is contained in:
Alastair Houghton
2025-12-02 10:51:09 +00:00
committed by GitHub
19 changed files with 147 additions and 115 deletions

View File

@@ -190,7 +190,7 @@ internal func _getClockRes(
nanoseconds: UnsafeMutablePointer<Int64>,
clock: CInt)
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
@_silgen_name("swift_sleep")
internal func _sleep(
seconds: Int64,

View File

@@ -113,7 +113,7 @@ extension ContinuousClock: Clock {
public func sleep(
until deadline: Instant, tolerance: Swift.Duration? = nil
) async throws {
if #available(StdlibDeploymentTarget 6.2, *) {
if #available(StdlibDeploymentTarget 6.3, *) {
try await Task._sleep(until: deadline,
tolerance: tolerance,
clock: self)

View File

@@ -17,7 +17,7 @@ import Swift
// Store the Timestamp in the executor private data, if it will fit; otherwise,
// use the allocator to allocate space for it and stash a pointer in the private
// data area.
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
extension ExecutorJob {
fileprivate var cooperativeExecutorTimestampIsIndirect: Bool {
return MemoryLayout<(Int, Int)>.size
@@ -99,7 +99,7 @@ extension ExecutorJob {
#if !$Embedded && !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
/// A wait queue is a specialised priority queue used to run a timer.
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
struct WaitQueue {
var queue: PriorityQueue<UnownedJob>
var clock: _ClockID
@@ -157,7 +157,7 @@ struct WaitQueue {
/// A co-operative executor that can be used as the main executor or as a
/// task executor.
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
final class CooperativeExecutor: Executor, @unchecked Sendable {
var runQueue: PriorityQueue<UnownedJob>
#if !$Embedded && !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
@@ -282,7 +282,7 @@ extension CooperativeExecutor: SchedulingExecutor {
}
#endif
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
extension CooperativeExecutor: RunLoopExecutor {
public func run() throws {
try runUntil { false }
@@ -340,13 +340,13 @@ extension CooperativeExecutor: RunLoopExecutor {
}
}
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
extension CooperativeExecutor: SerialExecutor {}
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
extension CooperativeExecutor: TaskExecutor {}
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
extension CooperativeExecutor: MainExecutor {}
#endif // !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY

View File

@@ -38,7 +38,7 @@ public protocol Executor: AnyObject, Sendable {
#if os(WASI) || !$Embedded
/// `true` if this is the main executor.
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
var isMainExecutor: Bool { get }
#endif // os(WASI) || !$Embedded
@@ -49,12 +49,12 @@ public protocol Executor: AnyObject, Sendable {
/// Executors that implement SchedulingExecutor should provide their
/// own copy of this method, which will allow the compiler to avoid a
/// potentially expensive runtime cast.
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
var asSchedulingExecutor: (any SchedulingExecutor)? { get }
#endif
}
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
public protocol SchedulingExecutor: Executor {
#if !$Embedded && !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
@@ -74,7 +74,7 @@ public protocol SchedulingExecutor: Executor {
/// - tolerance: The maximum additional delay permissible before the
/// job is executed. `nil` means no limit.
/// - clock: The clock used for the delay.
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
func enqueue<C: Clock>(_ job: consuming ExecutorJob,
after delay: C.Duration,
tolerance: C.Duration?,
@@ -94,7 +94,7 @@ public protocol SchedulingExecutor: Executor {
/// - tolerance: The maximum additional delay permissible before the
/// job is executed. `nil` means no limit.
/// - clock: The clock used for the delay.
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
func enqueue<C: Clock>(_ job: consuming ExecutorJob,
at instant: C.Instant,
tolerance: C.Duration?,
@@ -138,7 +138,7 @@ extension Executor {
/// Executors that implement SchedulingExecutor should provide their
/// own copy of this method, which will allow the compiler to avoid a
/// potentially expensive runtime cast.
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
public var asSchedulingExecutor: (any SchedulingExecutor)? {
return self as? SchedulingExecutor
}
@@ -162,19 +162,19 @@ extension Executor {
#if os(WASI) || !$Embedded
// This defaults to `false` so that existing third-party Executor
// implementations will work as expected.
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
public var isMainExecutor: Bool { false }
#endif // os(WASI) || !$Embedded
}
// Delay support
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
extension SchedulingExecutor {
#if !$Embedded && !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
public func enqueue<C: Clock>(_ job: consuming ExecutorJob,
after delay: C.Duration,
tolerance: C.Duration? = nil,
@@ -185,7 +185,7 @@ extension SchedulingExecutor {
tolerance: tolerance, clock: clock)
}
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
public func enqueue<C: Clock>(_ job: consuming ExecutorJob,
at instant: C.Instant,
tolerance: C.Duration? = nil,
@@ -383,7 +383,7 @@ public protocol SerialExecutor: Executor {
extension SerialExecutor {
#if os(WASI) || (!$Embedded && !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY)
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
public var isMainExecutor: Bool { return MainActor.executor._isSameExecutor(self) }
#endif // os(WASI) || (!$Embedded && !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY)
@@ -397,13 +397,13 @@ extension SerialExecutor {
}
#if SWIFT_CONCURRENCY_USES_DISPATCH
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
private var _dispatchQueue: OpaquePointer? {
return unsafe _getDispatchQueueForExecutor(self.asUnownedSerialExecutor())
}
#endif
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
internal func _isSameExecutor(_ rhs: some SerialExecutor) -> Bool {
if rhs === self {
return true
@@ -526,10 +526,10 @@ extension SerialExecutor {
}
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
extension SerialExecutor where Self: Equatable {
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
public func isSameExclusiveExecutionContext(other: Self) -> Bool {
return self == other
}
@@ -541,7 +541,7 @@ extension SerialExecutor where Self: Equatable {
/// The idea here is that some executors may work by running a loop
/// that processes events of some sort; we want a way to enter that loop,
/// and we would also like a way to trigger the loop to exit.
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
public protocol RunLoopExecutor: Executor {
/// Run the executor's run loop.
///
@@ -572,7 +572,7 @@ public protocol RunLoopExecutor: Executor {
func stop()
}
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
extension RunLoopExecutor {
public func runUntil(_ condition: () -> Bool) throws {
@@ -584,14 +584,14 @@ extension RunLoopExecutor {
/// The main executor must conform to these two protocols; we have to
/// make this a protocol for compatibility with Embedded Swift.
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
public protocol MainExecutor: RunLoopExecutor, SerialExecutor {
}
/// An ExecutorFactory is used to create the default main and task
/// executors.
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
public protocol ExecutorFactory {
#if os(WASI) || !$Embedded
/// Constructs and returns the main executor, which is started implicitly
@@ -607,7 +607,7 @@ public protocol ExecutorFactory {
@available(StdlibDeploymentTarget 6.3, *)
typealias DefaultExecutorFactory = PlatformExecutorFactory
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
@_silgen_name("swift_createExecutors")
public func _createExecutors<F: ExecutorFactory>(factory: F.Type) {
#if os(WASI) || (!$Embedded && !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY)
@@ -626,7 +626,7 @@ func _createDefaultExecutors() {
#if os(WASI) || (!$Embedded && !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY)
extension MainActor {
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
static var _executor: (any MainExecutor)? = nil
/// The main executor, which is started implicitly by the `async main`
@@ -634,7 +634,7 @@ extension MainActor {
///
/// Attempting to set this after the first `enqueue` on the main
/// executor is a fatal error.
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
public static var executor: any MainExecutor {
// It would be good if there was a Swift way to do this
_createDefaultExecutorsOnce()
@@ -642,7 +642,7 @@ extension MainActor {
}
/// An unowned version of the above, for performance
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
static var unownedExecutor: UnownedSerialExecutor {
_createDefaultExecutorsOnce()
return unsafe UnownedSerialExecutor(ordinary: _executor!)
@@ -651,7 +651,7 @@ extension MainActor {
#endif // os(WASI) || (!$Embedded && !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY)
extension Task where Success == Never, Failure == Never {
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
static var _defaultExecutor: (any TaskExecutor)? = nil
/// The default or global executor, which is the default place in which
@@ -659,7 +659,7 @@ extension Task where Success == Never, Failure == Never {
///
/// Attempting to set this after the first `enqueue` on the global
/// executor is a fatal error.
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
public static var defaultExecutor: any TaskExecutor {
// It would be good if there was a Swift way to do this
_createDefaultExecutorsOnce()
@@ -667,7 +667,7 @@ extension Task where Success == Never, Failure == Never {
}
/// An unowned version of the above, for performance
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
static var unownedDefaultExecutor: UnownedTaskExecutor {
_createDefaultExecutorsOnce()
return unsafe UnownedTaskExecutor(_defaultExecutor!)
@@ -686,7 +686,7 @@ extension Task where Success == Never, Failure == Never {
/// 3. The task executor for the current thread
///
/// If none of these exist, returns the default executor.
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
@_unavailableInEmbedded
public static var currentExecutor: any Executor {
if let activeExecutor = unsafe _getActiveExecutor().asSerialExecutor() {
@@ -700,7 +700,7 @@ extension Task where Success == Never, Failure == Never {
}
/// Get the preferred executor for the current `Task`, if any.
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
public static var preferredExecutor: (any TaskExecutor)? {
if let taskExecutor = unsafe _getPreferredTaskExecutor().asTaskExecutor() {
return taskExecutor
@@ -713,7 +713,7 @@ extension Task where Success == Never, Failure == Never {
///
/// This follows the same logic as `currentExecutor`, except that it ignores
/// any executor that isn't a `SchedulingExecutor`.
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
public static var currentSchedulingExecutor: (any SchedulingExecutor)? {
if let activeExecutor = unsafe _getActiveExecutor().asSerialExecutor(),
let scheduling = activeExecutor.asSchedulingExecutor {
@@ -806,7 +806,7 @@ public struct UnownedSerialExecutor: Sendable {
unsafe _executor_isComplexEquality(self)
}
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
public func asSerialExecutor() -> (any SerialExecutor)? {
// The low bits of the witness table are used to encode the executor kind.
// any SerialExecutor needs a raw witness table pointer, so mask off the low
@@ -843,13 +843,13 @@ public struct UnownedTaskExecutor: Sendable {
unsafe self.executor = Builtin.buildOrdinaryTaskExecutorRef(executor)
}
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
@inlinable
public init<E: TaskExecutor>(_ executor: __shared E) {
unsafe self.executor = Builtin.buildOrdinaryTaskExecutorRef(executor)
}
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
public func asTaskExecutor() -> (any TaskExecutor)? {
return unsafe unsafeBitCast(executor, to: (any TaskExecutor)?.self)
}

View File

@@ -17,19 +17,19 @@
import Swift
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
@_silgen_name("_swift_exit")
internal func _exit(result: CInt)
#if !$Embedded
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
@_silgen_name("_swift_task_isMainExecutorSwift")
internal func _isMainExecutor<E>(_ executor: E) -> Bool where E: SerialExecutor {
return executor.isMainExecutor
}
#endif
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
@_silgen_name("_swift_task_checkIsolatedSwift")
internal func checkIsolated<E>(executor: E) where E: SerialExecutor {
executor.checkIsolated()
@@ -40,7 +40,7 @@ internal func checkIsolated<E>(executor: E) where E: SerialExecutor {
/// -1: unknown
/// 0: not isolated
/// 1: isolated
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
@_silgen_name("_swift_task_isIsolatingCurrentContextSwift")
internal func isIsolatingCurrentContext<E>(executor: E) -> Int8
where E: SerialExecutor {
@@ -51,41 +51,41 @@ internal func isIsolatingCurrentContext<E>(executor: E) -> Int8
}
}
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
@_silgen_name("_swift_getActiveExecutor")
internal func _getActiveExecutor() -> UnownedSerialExecutor
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
@_silgen_name("_swift_getCurrentTaskExecutor")
internal func _getCurrentTaskExecutor() -> UnownedTaskExecutor
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
@_silgen_name("_swift_getPreferredTaskExecutor")
internal func _getPreferredTaskExecutor() -> UnownedTaskExecutor
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
@_silgen_name("swift_job_allocate")
internal func _jobAllocate(_ job: Builtin.Job,
_ capacity: Int) -> UnsafeMutableRawPointer
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
@_silgen_name("swift_job_deallocate")
internal func _jobDeallocate(_ job: Builtin.Job,
_ address: UnsafeMutableRawPointer)
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
@_silgen_name("swift_job_getPriority")
internal func _jobGetPriority(_ job: Builtin.Job) -> UInt8
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
@_silgen_name("swift_job_setPriority")
internal func _jobSetPriority(_ job: Builtin.Job, _ priority: UInt8)
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
@_silgen_name("swift_job_getKind")
internal func _jobGetKind(_ job: Builtin.Job) -> UInt8
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
@_silgen_name("swift_job_getExecutorPrivateData")
internal func _jobGetExecutorPrivateData(
_ job: Builtin.Job
@@ -93,38 +93,38 @@ internal func _jobGetExecutorPrivateData(
#if os(WASI) || !$Embedded
#if !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
@_silgen_name("swift_getMainExecutor")
internal func _getMainExecutorAsSerialExecutor() -> UnownedSerialExecutor {
return unsafe MainActor.unownedExecutor
}
#else
// For task-to-thread model, this is implemented in C++
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
@_silgen_name("swift_getMainExecutor")
internal func _getMainExecutorAsSerialExecutor() -> UnownedSerialExecutor
#endif // SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
#endif // os(WASI) || !$Embedded
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
@_silgen_name("swift_getDefaultExecutor")
internal func _getDefaultExecutorAsTaskExecutor() -> UnownedTaskExecutor {
return unsafe Task.unownedDefaultExecutor
}
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
@_silgen_name("swift_dispatchMain")
internal func _dispatchMain()
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
@_silgen_name("swift_dispatchEnqueueMain")
internal func _dispatchEnqueueMain(_ job: UnownedJob)
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
@_silgen_name("swift_dispatchEnqueueGlobal")
internal func _dispatchEnqueueGlobal(_ job: UnownedJob)
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
@_silgen_name("swift_dispatchEnqueueWithDeadline")
internal func _dispatchEnqueueWithDeadline(_ global: CBool,
_ sec: CLongLong,
@@ -134,7 +134,7 @@ internal func _dispatchEnqueueWithDeadline(_ global: CBool,
_ clock: CInt,
_ job: UnownedJob)
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
@_silgen_name("swift_dispatchAssertMainQueue")
internal func _dispatchAssertMainQueue()

View File

@@ -24,8 +24,12 @@ import Swift
@_silgen_name("swift_task_asyncMainDrainQueueImpl")
internal func drainMainQueue() {
#if !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
if #available(StdlibDeploymentTarget 6.3, *) {
try! MainActor.executor.run()
_exit(result: 0)
} else {
fatalError("this should never happen")
}
#else
fatalError("swift_task_asyncMainDrainQueue() not supported with task-to-thread")
#endif
@@ -37,24 +41,36 @@ internal func donateToGlobalExecutor(
condition: @convention(c) (_ ctx: UnsafeMutableRawPointer) -> CBool,
context: UnsafeMutableRawPointer
) {
if #available(StdlibDeploymentTarget 6.3, *) {
if let runnableExecutor = Task.defaultExecutor as? RunLoopExecutor {
try! runnableExecutor.runUntil { unsafe Bool(condition(context)) }
} else {
fatalError("Global executor does not support thread donation")
}
} else {
fatalError("this should never happen")
}
}
@available(SwiftStdlib 6.2, *)
@_silgen_name("swift_task_getMainExecutorImpl")
internal func getMainExecutor() -> UnownedSerialExecutor {
if #available(StdlibDeploymentTarget 6.3, *) {
return unsafe _getMainExecutorAsSerialExecutor()
} else {
fatalError("this should never happen")
}
}
@available(SwiftStdlib 6.2, *)
@_silgen_name("swift_task_enqueueMainExecutorImpl")
internal func enqueueOnMainExecutor(job unownedJob: UnownedJob) {
#if !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
if #available(StdlibDeploymentTarget 6.3, *) {
MainActor.executor.enqueue(unownedJob)
} else {
fatalError("this should never happen")
}
#else
fatalError("swift_task_enqueueMainExecutor() not supported for task-to-thread")
#endif
@@ -63,7 +79,11 @@ internal func enqueueOnMainExecutor(job unownedJob: UnownedJob) {
@available(SwiftStdlib 6.2, *)
@_silgen_name("swift_task_enqueueGlobalImpl")
internal func enqueueOnGlobalExecutor(job unownedJob: UnownedJob) {
if #available(StdlibDeploymentTarget 6.3, *) {
Task.defaultExecutor.enqueue(unownedJob)
} else {
fatalError("this should never happen")
}
}
#if !$Embedded
@@ -72,9 +92,13 @@ internal func enqueueOnGlobalExecutor(job unownedJob: UnownedJob) {
internal func enqueueOnGlobalExecutor(delay: CUnsignedLongLong,
job unownedJob: UnownedJob) {
#if !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
if #available(StdlibDeploymentTarget 6.3, *) {
Task.defaultExecutor.asSchedulingExecutor!.enqueue(ExecutorJob(unownedJob),
after: .nanoseconds(delay),
clock: .continuous)
} else {
fatalError("this should never happen")
}
#else
fatalError("swift_task_enqueueGlobalWithDelay() not supported for task-to-thread")
#endif
@@ -91,20 +115,28 @@ internal func enqueueOnGlobalExecutor(seconds: CLongLong,
#if !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
let delay = Duration.seconds(seconds) + Duration.nanoseconds(nanoseconds)
let leeway = Duration.seconds(leewaySeconds) + Duration.nanoseconds(leewayNanoseconds)
if #available(StdlibDeploymentTarget 6.3, *) {
switch clock {
case _ClockID.suspending.rawValue:
Task.defaultExecutor.asSchedulingExecutor!.enqueue(ExecutorJob(unownedJob),
Task.defaultExecutor.asSchedulingExecutor!.enqueue(
ExecutorJob(unownedJob),
after: delay,
tolerance: leeway,
clock: .suspending)
clock: .suspending
)
case _ClockID.continuous.rawValue:
Task.defaultExecutor.asSchedulingExecutor!.enqueue(ExecutorJob(unownedJob),
Task.defaultExecutor.asSchedulingExecutor!.enqueue(
ExecutorJob(unownedJob),
after: delay,
tolerance: leeway,
clock: .continuous)
clock: .continuous
)
default:
fatalError("Unknown clock ID \(clock)")
}
} else {
fatalError("this should never happen")
}
#else
fatalError("swift_task_enqueueGlobalWithDeadline() not supported for task-to-thread")
#endif

View File

@@ -34,7 +34,7 @@ import Swift
@_unavailableInEmbedded
public var globalConcurrentExecutor: any TaskExecutor {
get {
if #available(StdlibDeploymentTarget 6.2, *) {
if #available(StdlibDeploymentTarget 6.3, *) {
return Task.defaultExecutor
} else {
fatalError("we shouldn't get here; if we have, availability is broken")

View File

@@ -88,7 +88,7 @@ public struct UnownedJob: Sendable {
@available(StdlibDeploymentTarget 5.9, *)
public var priority: JobPriority {
let raw: UInt8
if #available(StdlibDeploymentTarget 6.2, *) {
if #available(StdlibDeploymentTarget 6.3, *) {
raw = _jobGetPriority(context)
} else {
fatalError("we shouldn't get here; if we have, availability is broken")
@@ -227,7 +227,7 @@ public struct Job: Sendable, ~Copyable {
public var priority: JobPriority {
let raw: UInt8
if #available(StdlibDeploymentTarget 6.2, *) {
if #available(StdlibDeploymentTarget 6.3, *) {
raw = _jobGetPriority(self.context)
} else {
fatalError("we shouldn't get here; if we have, availability is broken")
@@ -301,7 +301,7 @@ public struct ExecutorJob: Sendable, ~Copyable {
internal(set) public var priority: JobPriority {
get {
let raw: UInt8
if #available(StdlibDeploymentTarget 6.2, *) {
if #available(StdlibDeploymentTarget 6.3, *) {
raw = _jobGetPriority(self.context)
} else {
fatalError("we shouldn't get here; if we have, availability is broken")
@@ -309,7 +309,7 @@ public struct ExecutorJob: Sendable, ~Copyable {
return JobPriority(rawValue: raw)
}
set {
if #available(StdlibDeploymentTarget 6.2, *) {
if #available(StdlibDeploymentTarget 6.3, *) {
_jobSetPriority(self.context, newValue.rawValue)
} else {
fatalError("we shouldn't get here; if we have, availability is broken")
@@ -327,7 +327,7 @@ public struct ExecutorJob: Sendable, ~Copyable {
/// - body: The closure to execute.
///
/// Returns the result of executing the closure.
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
public func withUnsafeExecutorPrivateData<R, E>(body: (UnsafeMutableRawBufferPointer) throws(E) -> R) throws(E) -> R {
let base = unsafe _jobGetExecutorPrivateData(self.context)
let size = unsafe 2 * MemoryLayout<OpaquePointer>.stride
@@ -336,7 +336,7 @@ public struct ExecutorJob: Sendable, ~Copyable {
}
/// Kinds of schedulable jobs
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
@frozen
public struct Kind: Sendable, RawRepresentable {
public typealias RawValue = UInt8
@@ -357,7 +357,7 @@ public struct ExecutorJob: Sendable, ~Copyable {
}
/// What kind of job this is.
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
public var kind: Kind {
return Kind(rawValue: _jobGetKind(self.context))!
}
@@ -454,7 +454,7 @@ extension ExecutorJob {
// Helper to create a trampoline job to execute a job on a specified
// executor.
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
extension ExecutorJob {
/// Create a trampoline to enqueue the specified job on the specified
@@ -471,7 +471,7 @@ extension ExecutorJob {
///
/// A new ExecutorJob that will enqueue the specified job on the specified
/// executor.
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
public func createTrampoline(to executor: some Executor) -> ExecutorJob {
let flags = taskCreateFlags(
priority: TaskPriority(priority),
@@ -496,7 +496,7 @@ extension ExecutorJob {
}
// Stack-disciplined job-local allocator support
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
extension ExecutorJob {
/// Obtain a stack-disciplined job-local allocator.
@@ -971,7 +971,7 @@ public func _abiEnableAwaitContinuation() {
}
#if !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
@_silgen_name("_swift_createJobForTestingOnly")
public func _swift_createJobForTestingOnly(
priority: TaskPriority = TaskPriority.medium,

View File

@@ -13,7 +13,7 @@
import Swift
// This platform uses a single, global, CooperativeExecutor
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
public struct PlatformExecutorFactory: ExecutorFactory {
static let executor = CooperativeExecutor()
public static var mainExecutor: any MainExecutor { executor }

View File

@@ -15,7 +15,7 @@
import Swift
// The default executors for now are Dispatch-based
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
public struct PlatformExecutorFactory: ExecutorFactory {
public static let mainExecutor: any MainExecutor = DispatchMainExecutor()
public static let defaultExecutor: any TaskExecutor

View File

@@ -12,7 +12,7 @@
import Swift
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
public struct PlatformExecutorFactory: ExecutorFactory {
public static let mainExecutor: any MainExecutor = UnimplementedMainExecutor()
public static let defaultExecutor: any TaskExecutor = UnimplementedTaskExecutor()

View File

@@ -15,7 +15,7 @@
import Swift
// The default executors for now are Dispatch-based
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
public struct PlatformExecutorFactory: ExecutorFactory {
public static let mainExecutor: any MainExecutor = DispatchMainExecutor()
public static let defaultExecutor: any TaskExecutor =

View File

@@ -101,7 +101,7 @@ extension SuspendingClock: Clock {
public func sleep(
until deadline: Instant, tolerance: Swift.Duration? = nil
) async throws {
if #available(StdlibDeploymentTarget 6.2, *) {
if #available(StdlibDeploymentTarget 6.3, *) {
try await Task._sleep(until: deadline,
tolerance: tolerance,
clock: self)

View File

@@ -637,7 +637,7 @@ extension Task where Success == Never, Failure == Never {
continuation: continuation)
#if !$Embedded && !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
if #available(StdlibDeploymentTarget 6.2, *) {
if #available(StdlibDeploymentTarget 6.3, *) {
let executor = Task.currentExecutor
executor.enqueue(ExecutorJob(context: job))
@@ -884,7 +884,7 @@ internal func _runAsyncMain(_ asyncFun: @Sendable @escaping () async throws -> (
}
let job = Builtin.convertTaskToJob(theTask)
if #available(StdlibDeploymentTarget 6.2, *) {
if #available(StdlibDeploymentTarget 6.3, *) {
MainActor.executor.enqueue(ExecutorJob(context: job))
} else {
fatalError("we shouldn't get here; if we have, availability is broken")

View File

@@ -28,7 +28,7 @@ extension Task where Success == Never, Failure == Never {
priority: Int(Task.currentPriority.rawValue),
continuation: continuation)
if #available(StdlibDeploymentTarget 6.2, *) {
if #available(StdlibDeploymentTarget 6.3, *) {
#if !$Embedded
if let executor = Task.currentSchedulingExecutor {
executor.enqueue(ExecutorJob(context: job),
@@ -272,7 +272,7 @@ extension Task where Success == Never, Failure == Never {
let job = Builtin.convertTaskToJob(sleepTask)
if #available(StdlibDeploymentTarget 6.2, *) {
if #available(StdlibDeploymentTarget 6.3, *) {
#if !$Embedded
if let executor = Task.currentSchedulingExecutor {
executor.enqueue(ExecutorJob(context: job),

View File

@@ -116,7 +116,7 @@ extension Task where Success == Never, Failure == Never {
let job = Builtin.convertTaskToJob(sleepTask)
if #available(StdlibDeploymentTarget 6.2, *) {
if #available(StdlibDeploymentTarget 6.3, *) {
#if !$Embedded
if let executor = Task.currentSchedulingExecutor {
executor.enqueue(ExecutorJob(context: job),
@@ -136,7 +136,7 @@ extension Task where Success == Never, Failure == Never {
clock: clock)
let toleranceSeconds: Int64
let toleranceNanoseconds: Int64
if #available(StdlibDeploymentTarget 6.2, *) {
if #available(StdlibDeploymentTarget 6.3, *) {
if let tolerance = tolerance {
(toleranceSeconds, toleranceNanoseconds)
= durationComponents(for: tolerance, clock: clock)

View File

@@ -14,7 +14,7 @@ import Swift
// .. Main Executor ............................................................
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
public final class UnimplementedMainExecutor: MainExecutor, @unchecked Sendable {
public init() {}
@@ -45,7 +45,7 @@ public final class UnimplementedMainExecutor: MainExecutor, @unchecked Sendable
// .. Task Executor ............................................................
@available(StdlibDeploymentTarget 6.2, *)
@available(StdlibDeploymentTarget 6.3, *)
public final class UnimplementedTaskExecutor: TaskExecutor, @unchecked Sendable {
public init() {}

View File

@@ -203,7 +203,7 @@ await Task.detached { @SomeGlobalActor in
// CHECK: Testing a separate task off the main actor
print("Testing a separate task off the main actor")
await Task.detached {
if #available(SwiftStdlib 6.2, *) {
if #available(SwiftStdlib 6.3, *) {
// Skip tests on platforms that use the same executor for the main
// actor and the global concurrent executor.
guard Task.defaultExecutor !== MainActor.executor else { return }

View File

@@ -15,14 +15,14 @@
import Dispatch
import StdlibUnittest
@available(SwiftStdlib 6.2, *)
@available(SwiftStdlib 6.3, *)
actor MyActor {
public func doSleep() async {
try! await Task.sleep(for: .seconds(0.1))
}
}
@available(SwiftStdlib 6.2, *)
@available(SwiftStdlib 6.3, *)
final class TestExecutor: TaskExecutor, SchedulingExecutor, @unchecked Sendable {
var asScheduling: SchedulingExecutor? {
return self
@@ -58,7 +58,7 @@ final class TestExecutor: TaskExecutor, SchedulingExecutor, @unchecked Sendable
}
}
@available(SwiftStdlib 6.2, *)
@available(SwiftStdlib 6.3, *)
@main struct Main {
static func main() async {
let tests = TestSuite("sleep_executor")