From 852692676daae9bba82b8f775dc16eedea1c5ebd Mon Sep 17 00:00:00 2001 From: Alastair Houghton Date: Mon, 23 Jun 2025 16:45:13 +0100 Subject: [PATCH 1/5] [Concurrency] Updates after second SE pitch. We no longer attempt to convert timestamps from the passed-in `Clock` in order to allow any clock to work with any executor. Instead, executors that do not recognise a clock should call the `enqueue` function on that `Clock`, which lets the `Clock` itself decide how to proceed. Additionally, rename `SchedulableExecutor` to `SchedulingExecutor`. --- lib/SILGen/SILGen.cpp | 31 ++- stdlib/public/Concurrency/CFExecutor.swift | 2 + stdlib/public/Concurrency/Clock.swift | 23 ++ .../public/Concurrency/ContinuousClock.swift | 33 +++ .../Concurrency/CooperativeExecutor.swift | 165 +++++++++++---- .../public/Concurrency/DispatchExecutor.swift | 199 ++++++++---------- stdlib/public/Concurrency/Executor.swift | 55 +++-- .../public/Concurrency/ExecutorBridge.swift | 6 +- stdlib/public/Concurrency/ExecutorImpl.swift | 28 ++- .../public/Concurrency/PartialAsyncTask.swift | 70 ++++-- stdlib/public/Concurrency/PriorityQueue.swift | 14 ++ .../public/Concurrency/SuspendingClock.swift | 33 +++ stdlib/public/Concurrency/TaskSleep.swift | 8 +- .../Concurrency/TaskSleepDuration.swift | 95 +++++---- .../Inputs/macOS/arm64/concurrency/baseline | 5 + .../macOS/arm64/concurrency/baseline-asserts | 5 + .../Inputs/macOS/x86_64/concurrency/baseline | 5 + .../macOS/x86_64/concurrency/baseline-asserts | 5 + 18 files changed, 532 insertions(+), 250 deletions(-) diff --git a/lib/SILGen/SILGen.cpp b/lib/SILGen/SILGen.cpp index a467e4fbdd829..a31efddb10b1f 100644 --- a/lib/SILGen/SILGen.cpp +++ b/lib/SILGen/SILGen.cpp @@ -523,7 +523,36 @@ FuncDecl *SILGenModule::getExit() { Type SILGenModule::getConfiguredExecutorFactory() { auto &ctx = getASTContext(); - // Look in the main module for a typealias + // First look in the @main struct, if any + NominalTypeDecl *mainType = ctx.MainModule->getMainTypeDecl(); + if (mainType) { + SmallVector decls; + auto identifier = ctx.getIdentifier("DefaultExecutorFactory"); + mainType->lookupQualified(mainType, + DeclNameRef(identifier), + SourceLoc(), + NL_RemoveNonVisible | NL_RemoveOverridden + | NL_OnlyTypes | NL_ProtocolMembers, + decls); + for (auto decl : decls) { + TypeDecl *typeDecl = dyn_cast(decl); + if (typeDecl) { + if (auto *nominalDecl = dyn_cast(typeDecl)) { + return nominalDecl->getDeclaredType(); + } + + if (isa(typeDecl)) { + // We ignore associatedtype declarations; those with a default will + // turn into a `typealias` instead. + continue; + } + + return typeDecl->getDeclaredInterfaceType(); + } + } + } + + // Failing that, look at the top level Type factory = ctx.getNamedSwiftType(ctx.MainModule, "DefaultExecutorFactory"); // If we don't find it, fall back to _Concurrency.PlatformExecutorFactory diff --git a/stdlib/public/Concurrency/CFExecutor.swift b/stdlib/public/Concurrency/CFExecutor.swift index 633d7f6b87d8b..067cd94991904 100644 --- a/stdlib/public/Concurrency/CFExecutor.swift +++ b/stdlib/public/Concurrency/CFExecutor.swift @@ -43,6 +43,7 @@ enum CoreFoundation { // .. Main Executor ............................................................ +/// A CFRunLoop-based main executor (Apple platforms only) @available(StdlibDeploymentTarget 6.2, *) final class CFMainExecutor: DispatchMainExecutor, @unchecked Sendable { @@ -58,6 +59,7 @@ final class CFMainExecutor: DispatchMainExecutor, @unchecked Sendable { // .. Task Executor ............................................................ +/// A `TaskExecutor` to match `CFMainExecutor` (Apple platforms only) @available(StdlibDeploymentTarget 6.2, *) final class CFTaskExecutor: DispatchGlobalTaskExecutor, @unchecked Sendable { diff --git a/stdlib/public/Concurrency/Clock.swift b/stdlib/public/Concurrency/Clock.swift index 3f579ef0b4b80..099ed1b5e2ce3 100644 --- a/stdlib/public/Concurrency/Clock.swift +++ b/stdlib/public/Concurrency/Clock.swift @@ -43,6 +43,28 @@ public protocol Clock: Sendable { #endif } +#if !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY +extension Clock { + // The default implementation works by creating a trampoline and calling + // the run() method. + @available(StdlibDeploymentTarget 6.2, *) + func enqueue(_ job: consuming ExecutorJob, + on executor: some Executor, + at instant: Instant, tolerance: Duration?) { + let trampoline = job.createTrampoline(to: executor) + run(trampoline, at: instant, tolerance: tolerance) + } + + // Clocks that do not implement run will fatalError() if you try to use + // them with an executor that does not understand them. + @available(StdlibDeploymentTarget 6.2, *) + func run(_ job: consuming ExecutorJob, + at instant: Instant, tolerance: Duration?) { + fatalError("\(Self.self) does not implement run(_:at:tolerance:).") + } +} +#endif // !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY + @available(StdlibDeploymentTarget 5.7, *) extension Clock { /// Measure the elapsed time to execute a closure. @@ -117,6 +139,7 @@ extension Clock { enum _ClockID: Int32 { case continuous = 1 case suspending = 2 + case walltime = 3 } @available(StdlibDeploymentTarget 5.7, *) diff --git a/stdlib/public/Concurrency/ContinuousClock.swift b/stdlib/public/Concurrency/ContinuousClock.swift index 1ce6126345800..f10682cf4cfbb 100644 --- a/stdlib/public/Concurrency/ContinuousClock.swift +++ b/stdlib/public/Concurrency/ContinuousClock.swift @@ -201,3 +201,36 @@ extension ContinuousClock.Instant: InstantProtocol { rhs.duration(to: lhs) } } + +#if !$Embedded && !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY +@available(StdlibDeploymentTarget 6.2, *) +extension ContinuousClock { + + public func run(_ job: consuming ExecutorJob, + at instant: Instant, + tolerance: Duration?) { + guard let executor = Task.currentSchedulingExecutor else { + fatalError("no scheduling executor is available") + } + + executor.enqueue(job, at: instant, + tolerance: tolerance, + clock: self) + } + + public func enqueue(_ job: consuming ExecutorJob, + on executor: some Executor, + at instant: Instant, + tolerance: Duration?) { + if let schedulingExecutor = executor.asSchedulingExecutor { + schedulingExecutor.enqueue(job, at: instant, + tolerance: tolerance, + clock: self) + } else { + let trampoline = job.createTrampoline(to: executor) + run(trampoline, at: instant, tolerance: tolerance) + } + } + +} +#endif diff --git a/stdlib/public/Concurrency/CooperativeExecutor.swift b/stdlib/public/Concurrency/CooperativeExecutor.swift index 7cf8e90b2e658..78036141c808e 100644 --- a/stdlib/public/Concurrency/CooperativeExecutor.swift +++ b/stdlib/public/Concurrency/CooperativeExecutor.swift @@ -97,16 +97,77 @@ 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, *) +struct WaitQueue { + var queue: PriorityQueue + var clock: _ClockID + + init(clock: _ClockID) { + queue = PriorityQueue(compare: { + ExecutorJob($0).cooperativeExecutorTimestamp + < ExecutorJob($1).cooperativeExecutorTimestamp + }) + self.clock = clock + } + + var currentTime: CooperativeExecutor.Timestamp { + var now: CooperativeExecutor.Timestamp = .zero + unsafe _getTime(seconds: &now.seconds, + nanoseconds: &now.nanoseconds, + clock: clock.rawValue) + return now + } + + mutating func enqueue(_ job: consuming ExecutorJob, + after delay: CooperativeExecutor.Duration) { + let deadline = currentTime + delay + job.setupCooperativeExecutorTimestamp() + job.cooperativeExecutorTimestamp = deadline + queue.push(UnownedJob(job)) + } + + mutating func forEachReadyJob(body: (consuming ExecutorJob) -> ()) { + let now = currentTime + while let job = queue.pop( + when: { + ExecutorJob($0).cooperativeExecutorTimestamp < now + }) { + var theJob = ExecutorJob(job) + theJob.clearCooperativeExecutorTimestamp() + body(theJob) + } + } + + var timeToNextJob: CooperativeExecutor.Duration? { + if let job = queue.top { + let deadline = ExecutorJob(job).cooperativeExecutorTimestamp + let now = currentTime + if deadline > now { + return deadline - now + } else { + return CooperativeExecutor.Duration(seconds: 0, nanoseconds: 0) + } + } + return nil + } +} +#endif + /// A co-operative executor that can be used as the main executor or as a /// task executor. @available(StdlibDeploymentTarget 6.2, *) -class CooperativeExecutor: Executor, @unchecked Sendable { +final class CooperativeExecutor: Executor, @unchecked Sendable { var runQueue: PriorityQueue - var waitQueue: PriorityQueue + #if !$Embedded && !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY + var suspendingWaitQueue = WaitQueue(clock: .suspending) + var continuousWaitQueue = WaitQueue(clock: .continuous) + #endif var shouldStop: Bool = false /// Internal representation of a duration for CooperativeExecutor - struct Duration { + struct Duration: Comparable { var seconds: Int64 var nanoseconds: Int64 @@ -120,6 +181,16 @@ class CooperativeExecutor: Executor, @unchecked Sendable { self.seconds = seconds self.nanoseconds = attoseconds / 1_000_000_000 } + + static func == (lhs: Duration, rhs: Duration) -> Bool { + return lhs.seconds == rhs.seconds && lhs.nanoseconds == rhs.nanoseconds + } + static func < (lhs: Duration, rhs: Duration) -> Bool { + return lhs.seconds < rhs.seconds || ( + lhs.seconds == rhs.seconds + && lhs.nanoseconds < rhs.nanoseconds + ) + } } /// Internal representation of a timestamp for CooperativeExecutor @@ -163,11 +234,6 @@ class CooperativeExecutor: Executor, @unchecked Sendable { public init() { runQueue = PriorityQueue(compare: { $0.priority > $1.priority }) - waitQueue = - PriorityQueue(compare: { - ExecutorJob($0).cooperativeExecutorTimestamp - < ExecutorJob($1).cooperativeExecutorTimestamp - }) } public func enqueue(_ job: consuming ExecutorJob) { @@ -175,17 +241,21 @@ class CooperativeExecutor: Executor, @unchecked Sendable { } public var isMainExecutor: Bool { true } - - public var asSchedulable: any SchedulableExecutor { self } } +#if !$Embedded && !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY @available(StdlibDeploymentTarget 6.2, *) -extension CooperativeExecutor: SchedulableExecutor { - var currentTime: Timestamp { +extension CooperativeExecutor: SchedulingExecutor { + + public var asScheduling: (any SchedulingExecutor)? { + return self + } + + func currentTime(clock: _ClockID) -> Timestamp { var now: Timestamp = .zero unsafe _getTime(seconds: &now.seconds, nanoseconds: &now.nanoseconds, - clock: _ClockID.suspending.rawValue) + clock: clock.rawValue) return now } @@ -193,18 +263,24 @@ extension CooperativeExecutor: SchedulableExecutor { after delay: C.Duration, tolerance: C.Duration? = nil, clock: C) { - guard let swiftDuration = delay as? Swift.Duration else { - fatalError("Unsupported clock") + // If it's a clock we know, get the duration to wait + if let _ = clock as? ContinuousClock { + let continuousDuration = delay as! ContinuousClock.Duration + let duration = Duration(from: continuousDuration) + continuousWaitQueue.enqueue(job, after: duration) + } else if let _ = clock as? SuspendingClock { + let suspendingDuration = delay as! SuspendingClock.Duration + let duration = Duration(from: suspendingDuration) + suspendingWaitQueue.enqueue(job, after: duration) + } else { + clock.enqueue(job, on: self, at: clock.now.advanced(by: delay), + tolerance: tolerance) + return } - - let duration = Duration(from: swiftDuration) - let deadline = self.currentTime + duration - - job.setupCooperativeExecutorTimestamp() - job.cooperativeExecutorTimestamp = deadline - waitQueue.push(UnownedJob(job)) } + } +#endif @available(StdlibDeploymentTarget 6.2, *) extension CooperativeExecutor: RunLoopExecutor { @@ -215,36 +291,47 @@ extension CooperativeExecutor: RunLoopExecutor { public func runUntil(_ condition: () -> Bool) throws { shouldStop = false while !shouldStop && !condition() { - // Process the timer queue - let now = currentTime - while let job = waitQueue.pop(when: { - ExecutorJob($0).cooperativeExecutorTimestamp <= now - }) { - var theJob = ExecutorJob(job) - theJob.clearCooperativeExecutorTimestamp() - runQueue.push(job) + #if !$Embedded && !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY + // Process the timer queues + suspendingWaitQueue.forEachReadyJob { + runQueue.push(UnownedJob($0)) + } + continuousWaitQueue.forEachReadyJob { + runQueue.push(UnownedJob($0)) } + #endif // Now run any queued jobs - while let job = runQueue.pop() { + var runQ = runQueue.take() + while let job = runQ.pop() { unsafe ExecutorJob(job).runSynchronously( on: self.asUnownedSerialExecutor() ) } + #if !$Embedded && !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY // Finally, wait until the next deadline - if let job = waitQueue.top { - let deadline = ExecutorJob(job).cooperativeExecutorTimestamp - let now = self.currentTime - if deadline > now { - let toWait = deadline - now - _sleep(seconds: toWait.seconds, - nanoseconds: toWait.nanoseconds) + var toWait: Duration? = suspendingWaitQueue.timeToNextJob + + if let continuousToWait = continuousWaitQueue.timeToNextJob { + if toWait == nil || continuousToWait < toWait! { + toWait = continuousToWait } - } else { + } + + if let toWait { + _sleep(seconds: toWait.seconds, + nanoseconds: toWait.nanoseconds) + } else if runQueue.isEmpty { + // Stop if no more jobs are available + break + } + #else // $Embedded || SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY + if runQueue.isEmpty { // Stop if no more jobs are available break } + #endif } } diff --git a/stdlib/public/Concurrency/DispatchExecutor.swift b/stdlib/public/Concurrency/DispatchExecutor.swift index 2940bab30c67f..0910848ccd96b 100644 --- a/stdlib/public/Concurrency/DispatchExecutor.swift +++ b/stdlib/public/Concurrency/DispatchExecutor.swift @@ -23,8 +23,10 @@ import Swift // .. Main Executor ............................................................ +/// A Dispatch-based main executor. @available(StdlibDeploymentTarget 6.2, *) -class DispatchMainExecutor: RunLoopExecutor, @unchecked Sendable { +class DispatchMainExecutor: RunLoopExecutor, SchedulingExecutor, + @unchecked Sendable { var threaded = false public init() {} @@ -41,6 +43,18 @@ class DispatchMainExecutor: RunLoopExecutor, @unchecked Sendable { public func stop() { fatalError("DispatchMainExecutor cannot be stopped") } + + var asScheduling: (any SchedulingExecutor)? { + return self + } + + public func enqueue(_ job: consuming ExecutorJob, + at instant: C.Instant, + tolerance: C.Duration? = nil, + clock: C) { + _dispatchEnqueue(job, at: instant, tolerance: tolerance, clock: clock, + executor: self, global: false) + } } @available(StdlibDeploymentTarget 6.2, *) @@ -57,41 +71,14 @@ extension DispatchMainExecutor: SerialExecutor { } } -@available(StdlibDeploymentTarget 6.2, *) -extension DispatchMainExecutor: SchedulableExecutor { - public var asSchedulable: SchedulableExecutor? { - return self - } - - public func enqueue(_ job: consuming ExecutorJob, - at instant: C.Instant, - tolerance: C.Duration? = nil, - clock: C) { - let tolSec, tolNanosec: CLongLong - if let tolerance = tolerance { - (tolSec, tolNanosec) = delay(from: tolerance, clock: clock) - } else { - tolSec = 0 - tolNanosec = -1 - } - - let (clockID, seconds, nanoseconds) = timestamp(for: instant, clock: clock) - - _dispatchEnqueueWithDeadline(CBool(false), - CLongLong(seconds), CLongLong(nanoseconds), - CLongLong(tolSec), CLongLong(tolNanosec), - clockID.rawValue, - UnownedJob(job)) - } -} - @available(StdlibDeploymentTarget 6.2, *) extension DispatchMainExecutor: MainExecutor {} // .. Task Executor ............................................................ +/// A Dispatch-based `TaskExecutor` @available(StdlibDeploymentTarget 6.2, *) -class DispatchGlobalTaskExecutor: TaskExecutor, SchedulableExecutor, +class DispatchGlobalTaskExecutor: TaskExecutor, SchedulingExecutor, @unchecked Sendable { public init() {} @@ -101,114 +88,98 @@ class DispatchGlobalTaskExecutor: TaskExecutor, SchedulableExecutor, public var isMainExecutor: Bool { false } + var asScheduling: (any SchedulingExecutor)? { + return self + } + public func enqueue(_ job: consuming ExecutorJob, at instant: C.Instant, tolerance: C.Duration? = nil, clock: C) { - let tolSec, tolNanosec: CLongLong - if let tolerance = tolerance { - (tolSec, tolNanosec) = delay(from: tolerance, clock: clock) - } else { - tolSec = 0 - tolNanosec = -1 - } - - let (clockID, seconds, nanoseconds) = timestamp(for: instant, clock: clock) - - _dispatchEnqueueWithDeadline(CBool(true), - CLongLong(seconds), CLongLong(nanoseconds), - CLongLong(tolSec), CLongLong(tolNanosec), - clockID.rawValue, - UnownedJob(job)) + _dispatchEnqueue(job, at: instant, tolerance: tolerance, clock: clock, + executor: self, global: true) } } // .. Clock Support ............................................................ -/// DispatchMainExecutor and DispatchTaskExecutor both implement this -/// protocol. -/// -/// It is used to help convert instants and durations from arbitrary `Clock`s -/// to Dispatch's time base. -@available(StdlibDeploymentTarget 6.2, *) -protocol DispatchExecutorProtocol: Executor { - - /// Convert an `Instant` from the specified clock to a tuple identifying - /// the Dispatch clock and the seconds and nanoseconds components. - /// - /// Parameters: - /// - /// - for instant: The `Instant` to convert. - /// - clock: The `Clock` instant that the `Instant` came from. - /// - /// Returns: A tuple of `(clockID, seconds, nanoseconds)`. - func timestamp(for instant: C.Instant, clock: C) - -> (clockID: DispatchClockID, seconds: Int64, nanoseconds: Int64) - - /// Convert a `Duration` from the specified clock to a tuple containing - /// seconds and nanosecond components. - func delay(from duration: C.Duration, clock: C) - -> (seconds: Int64, nanoseconds: Int64) - -} - /// An enumeration identifying one of the Dispatch-supported clocks enum DispatchClockID: CInt { case continuous = 1 case suspending = 2 + case walltime = 3 } -@available(StdlibDeploymentTarget 6.2, *) -extension DispatchExecutorProtocol { - - func clamp(_ components: (seconds: Int64, attoseconds: Int64)) - -> (seconds: Int64, attoseconds: Int64) { - if components.seconds < 0 - || components.seconds == 0 && components.attoseconds < 0 { - return (seconds: 0, attoseconds: 0) - } - return (seconds: components.seconds, attoseconds: components.attoseconds) +fileprivate func clamp(_ components: (seconds: Int64, attoseconds: Int64)) + -> (seconds: Int64, attoseconds: Int64) { + if components.seconds < 0 + || components.seconds == 0 && components.attoseconds < 0 { + return (seconds: 0, attoseconds: 0) } + return (seconds: components.seconds, attoseconds: components.attoseconds) +} - func timestamp(for instant: C.Instant, clock: C) - -> (clockID: DispatchClockID, seconds: Int64, nanoseconds: Int64) { - if clock is ContinuousClock { - let instant = instant as! ContinuousClock.Instant - let (seconds, attoseconds) = clamp(instant._value.components) - let nanoseconds = attoseconds / 1_000_000_000 - return (clockID: .continuous, - seconds: Int64(seconds), - nanoseconds: Int64(nanoseconds)) - } else if clock is SuspendingClock { - let instant = instant as! SuspendingClock.Instant - let (seconds, attoseconds) = clamp(instant._value.components) - let nanoseconds = attoseconds / 1_000_000_000 - return (clockID: .suspending, - seconds: Int64(seconds), - nanoseconds: Int64(nanoseconds)) - } else { - fatalError("Unknown clock") - } - } +fileprivate func delay(from duration: Swift.Duration) -> ( + seconds: Int64, nanoseconds: Int64 +) { + let (seconds, attoseconds) = clamp(duration.components) + let nanoseconds = attoseconds / 1_000_000_000 + return (seconds: seconds, nanoseconds: nanoseconds) +} - func delay(from duration: C.Duration, clock: C) - -> (seconds: Int64, nanoseconds: Int64) { - guard let swiftDuration = duration as? Swift.Duration else { - fatalError("Unsupported clock") - } - let (seconds, attoseconds) = clamp(swiftDuration.components) - let nanoseconds = attoseconds / 1_000_000_000 - return (seconds: seconds, nanoseconds: nanoseconds) +fileprivate func timestamp(for instant: C.Instant, clock: C) + -> (clockID: _ClockID, seconds: Int64, nanoseconds: Int64)? { + if let continuousClock = clock as? ContinuousClock { + return continuousClock.timestamp(for: instant as! ContinuousClock.Instant) + } else if let suspendingClock = clock as? SuspendingClock { + return suspendingClock.timestamp(for: instant as! SuspendingClock.Instant) } - + return nil } -@available(StdlibDeploymentTarget 6.2, *) -extension DispatchGlobalTaskExecutor: DispatchExecutorProtocol { +fileprivate func durationComponents(for duration: C.Duration, clock: C) + -> (seconds: Int64, nanoseconds: Int64) { + if let continuousClock = clock as? ContinuousClock { + return continuousClock.durationComponents(for: duration as! ContinuousClock.Duration) + } else if let suspendingClock = clock as? SuspendingClock { + return suspendingClock.durationComponents(for: duration as! SuspendingClock.Duration) + } + // This shouldn't be reachable + fatalError("unknown clock in Dispatch Executor") } @available(StdlibDeploymentTarget 6.2, *) -extension DispatchMainExecutor: DispatchExecutorProtocol { +fileprivate func _dispatchEnqueue( + _ job: consuming ExecutorJob, + at instant: C.Instant, + tolerance: C.Duration?, + clock: C, + executor: E, + global: Bool +) { + // If it's a clock we know, convert it to something we can use; otherwise, + // call the clock's `enqueue` function to schedule the enqueue of the job. + + guard let (clockID, seconds, nanoseconds) = timestamp(for: instant, + clock: clock) else { + clock.enqueue(job, on: executor, at: instant, tolerance: tolerance) + return + } + + let tolSec: Int64, tolNanosec: Int64 + if let tolerance = tolerance { + (tolSec, tolNanosec) = durationComponents(for: tolerance, + clock: clock) + } else { + tolSec = 0 + tolNanosec = -1 + } + + _dispatchEnqueueWithDeadline(CBool(global), + CLongLong(seconds), CLongLong(nanoseconds), + CLongLong(tolSec), CLongLong(tolNanosec), + clockID.rawValue, + UnownedJob(job)) } #endif // !$Embedded && !os(WASI) diff --git a/stdlib/public/Concurrency/Executor.swift b/stdlib/public/Concurrency/Executor.swift index 94429fc8373d2..07a4f80f5dc58 100644 --- a/stdlib/public/Concurrency/Executor.swift +++ b/stdlib/public/Concurrency/Executor.swift @@ -38,7 +38,8 @@ public protocol Executor: AnyObject, Sendable { } -protocol SchedulableExecutor: Executor { +@available(StdlibDeploymentTarget 6.2, *) +protocol SchedulingExecutor: Executor { #if !$Embedded && !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY @@ -103,15 +104,20 @@ extension Actor { } extension Executor { - /// Return this executable as a SchedulableExecutor, or nil if that is + + #if !$Embedded + /// Return this executor as a SchedulingExecutor, or nil if that is /// unsupported. /// - /// Executors that implement SchedulableExecutor should provide their + /// Executors that implement SchedulingExecutor should provide their /// own copy of this method, which will allow the compiler to avoid a /// potentially expensive runtime cast. - var asSchedulable: SchedulableExecutor? { - return self as? SchedulableExecutor + @available(StdlibDeploymentTarget 6.2, *) + var asSchedulingExecutor: (any SchedulingExecutor)? { + return self as? SchedulingExecutor } + #endif + } extension Executor { @@ -136,7 +142,8 @@ extension Executor { } // Delay support -extension SchedulableExecutor { +@available(StdlibDeploymentTarget 6.2, *) +extension SchedulingExecutor { #if !$Embedded && !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY @@ -542,7 +549,7 @@ extension RunLoopExecutor { } -/// The main executor must conform to these three protocols; we have to +/// The main executor must conform to these two protocols; we have to /// make this a protocol for compatibility with Embedded Swift. protocol MainExecutor: RunLoopExecutor, SerialExecutor { } @@ -598,6 +605,13 @@ extension MainActor { _createDefaultExecutorsOnce() return _executor! } + + /// An unowned version of the above, for performance + @available(StdlibDeploymentTarget 6.2, *) + static var unownedExecutor: UnownedSerialExecutor { + _createDefaultExecutorsOnce() + return unsafe UnownedSerialExecutor(ordinary: _executor!) + } } #endif // !$Embedded && !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY @@ -650,29 +664,32 @@ extension Task where Success == Never, Failure == Never { return nil } - /// Get the current *schedulable* executor, if any. + #if !$Embedded + /// Get the current *scheduling* executor, if any. /// /// This follows the same logic as `currentExecutor`, except that it ignores - /// any executor that isn't a `SchedulableExecutor`. - @_unavailableInEmbedded - static var currentSchedulableExecutor: (any SchedulableExecutor)? { + /// any executor that isn't a `SchedulingExecutor`. + @available(StdlibDeploymentTarget 6.2, *) + static var currentSchedulingExecutor: (any SchedulingExecutor)? { if let activeExecutor = unsafe _getActiveExecutor().asSerialExecutor(), - let schedulable = activeExecutor.asSchedulable { - return schedulable + let scheduling = activeExecutor.asSchedulingExecutor { + return scheduling } if let taskExecutor = unsafe _getPreferredTaskExecutor().asTaskExecutor(), - let schedulable = taskExecutor.asSchedulable { - return schedulable + let scheduling = taskExecutor.asSchedulingExecutor { + return scheduling } if let taskExecutor = unsafe _getCurrentTaskExecutor().asTaskExecutor(), - let schedulable = taskExecutor.asSchedulable { - return schedulable + let scheduling = taskExecutor.asSchedulingExecutor { + return scheduling } - if let schedulable = defaultExecutor.asSchedulable { - return schedulable + if let scheduling = defaultExecutor.asSchedulingExecutor { + return scheduling } return nil } + #endif + } diff --git a/stdlib/public/Concurrency/ExecutorBridge.swift b/stdlib/public/Concurrency/ExecutorBridge.swift index 5c34b8febf4a1..033dc98aa0973 100644 --- a/stdlib/public/Concurrency/ExecutorBridge.swift +++ b/stdlib/public/Concurrency/ExecutorBridge.swift @@ -91,14 +91,14 @@ internal func _jobGetExecutorPrivateData( #if !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY @available(StdlibDeploymentTarget 6.2, *) @_silgen_name("swift_getMainExecutor") -internal func _getMainExecutorAsSerialExecutor() -> (any SerialExecutor)? { - return MainActor.executor +internal func _getMainExecutorAsSerialExecutor() -> UnownedSerialExecutor { + return unsafe MainActor.unownedExecutor } #else // For task-to-thread model, this is implemented in C++ @available(StdlibDeploymentTarget 6.2, *) @_silgen_name("swift_getMainExecutor") -internal func _getMainExecutorAsSerialExecutor() -> (any SerialExecutor)? +internal func _getMainExecutorAsSerialExecutor() -> UnownedSerialExecutor #endif // SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY #endif // !$Embedded diff --git a/stdlib/public/Concurrency/ExecutorImpl.swift b/stdlib/public/Concurrency/ExecutorImpl.swift index 7ac153d2a3704..52ed84d0f71ef 100644 --- a/stdlib/public/Concurrency/ExecutorImpl.swift +++ b/stdlib/public/Concurrency/ExecutorImpl.swift @@ -47,11 +47,7 @@ internal func donateToGlobalExecutor( @available(SwiftStdlib 6.2, *) @_silgen_name("swift_task_getMainExecutorImpl") internal func getMainExecutor() -> UnownedSerialExecutor { - let executor = _getMainExecutorAsSerialExecutor() - if let executor { - return unsafe executor.asUnownedSerialExecutor() - } - return unsafe unsafeBitCast(executor, to: UnownedSerialExecutor.self) + return unsafe _getMainExecutorAsSerialExecutor() } @available(SwiftStdlib 6.2, *) @@ -76,9 +72,9 @@ internal func enqueueOnGlobalExecutor(job unownedJob: UnownedJob) { internal func enqueueOnGlobalExecutor(delay: CUnsignedLongLong, job unownedJob: UnownedJob) { #if !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY - Task.defaultExecutor.asSchedulable!.enqueue(ExecutorJob(unownedJob), - after: .nanoseconds(delay), - clock: .continuous) + Task.defaultExecutor.asSchedulingExecutor!.enqueue(ExecutorJob(unownedJob), + after: .nanoseconds(delay), + clock: .continuous) #else fatalError("swift_task_enqueueGlobalWithDelay() not supported for task-to-thread") #endif @@ -97,15 +93,15 @@ internal func enqueueOnGlobalExecutor(seconds: CLongLong, let leeway = Duration.seconds(leewaySeconds) + Duration.nanoseconds(leewayNanoseconds) switch clock { case _ClockID.suspending.rawValue: - Task.defaultExecutor.asSchedulable!.enqueue(ExecutorJob(unownedJob), - after: delay, - tolerance: leeway, - clock: .suspending) + Task.defaultExecutor.asSchedulingExecutor!.enqueue(ExecutorJob(unownedJob), + after: delay, + tolerance: leeway, + clock: .suspending) case _ClockID.continuous.rawValue: - Task.defaultExecutor.asSchedulable!.enqueue(ExecutorJob(unownedJob), - after: delay, - tolerance: leeway, - clock: .continuous) + Task.defaultExecutor.asSchedulingExecutor!.enqueue(ExecutorJob(unownedJob), + after: delay, + tolerance: leeway, + clock: .continuous) default: fatalError("Unknown clock ID \(clock)") } diff --git a/stdlib/public/Concurrency/PartialAsyncTask.swift b/stdlib/public/Concurrency/PartialAsyncTask.swift index bf2175a599a46..1a1a69cf5145e 100644 --- a/stdlib/public/Concurrency/PartialAsyncTask.swift +++ b/stdlib/public/Concurrency/PartialAsyncTask.swift @@ -309,7 +309,9 @@ public struct ExecutorJob: Sendable, ~Copyable { } /// Execute a closure, passing it the bounds of the executor private data - /// for the job. + /// for the job. The executor is responsible for ensuring that any resources + /// referenced from the private data area are cleared up prior to running the + /// job. /// /// Parameters: /// @@ -441,6 +443,48 @@ extension ExecutorJob { } } +// Helper to create a trampoline job to execute a job on a specified +// executor. +extension ExecutorJob { + + /// Create a trampoline to enqueue the specified job on the specified + /// executor. + /// + /// This is useful in conjunction with the `Clock.run()` API, which + /// runs a job on an unspecified executor. + /// + /// Parameters: + /// + /// - to executor: The `Executor` on which it should be enqueued. + /// + /// Returns: + /// + /// A new ExecutorJob that will enqueue the specified job on the specified + /// executor. + @available(StdlibDeploymentTarget 6.2, *) + public func createTrampoline(to executor: some Executor) -> ExecutorJob { + let flags = taskCreateFlags( + priority: TaskPriority(priority), + isChildTask: false, + copyTaskLocals: false, + inheritContext: false, + enqueueJob: false, + addPendingGroupTaskUnconditionally: false, + isDiscardingTask: false, + isSynchronousStart: false + ) + + let unownedJob = UnownedJob(context: self.context) + let (trampolineTask, _) = Builtin.createAsyncTask(flags) { + executor.enqueue(unownedJob) + } + let trampoline = Builtin.convertTaskToJob(trampolineTask) + + return ExecutorJob(context: trampoline) + } + +} + // Stack-disciplined job-local allocator support @available(StdlibDeploymentTarget 6.2, *) extension ExecutorJob { @@ -459,9 +503,8 @@ extension ExecutorJob { /// A job-local stack-disciplined allocator. /// /// This can be used to allocate additional data required by an - /// executor implementation; memory allocated in this manner will - /// be released automatically when the job is disposed of by the - /// runtime. + /// executor implementation; memory allocated in this manner must + /// be released by the executor before the job is executed. /// /// N.B. Because this allocator is stack disciplined, explicitly /// deallocating memory out-of-order will cause your program to abort. @@ -489,23 +532,20 @@ extension ExecutorJob { return unsafe UnsafeMutableBufferPointer(start: typedBase, count: capacity) } - /// Deallocate previously allocated memory. Note that the task - /// allocator is stack disciplined, so if you deallocate a block of - /// memory, all memory allocated after that block is also deallocated. + /// Deallocate previously allocated memory. You must do this in + /// reverse order of allocations, prior to running the job. public func deallocate(_ buffer: UnsafeMutableRawBufferPointer) { unsafe _jobDeallocate(context, buffer.baseAddress!) } - /// Deallocate previously allocated memory. Note that the task - /// allocator is stack disciplined, so if you deallocate a block of - /// memory, all memory allocated after that block is also deallocated. + /// Deallocate previously allocated memory. You must do this in + /// reverse order of allocations, prior to running the job. public func deallocate(_ pointer: UnsafeMutablePointer) { unsafe _jobDeallocate(context, UnsafeMutableRawPointer(pointer)) } - /// Deallocate previously allocated memory. Note that the task - /// allocator is stack disciplined, so if you deallocate a block of - /// memory, all memory allocated after that block is also deallocated. + /// Deallocate previously allocated memory. You must do this in + /// reverse order of allocations, prior to running the job. public func deallocate(_ buffer: UnsafeMutableBufferPointer) { unsafe _jobDeallocate(context, UnsafeMutableRawPointer(buffer.baseAddress!)) } @@ -542,12 +582,12 @@ public struct JobPriority: Sendable { public var rawValue: RawValue } -@available(SwiftStdlib 5.9, *) +@available(StdlibDeploymentTarget 5.9, *) extension TaskPriority { /// Convert this ``UnownedJob/Priority`` to a ``TaskPriority``. /// /// Most values are directly interchangeable, but this initializer reserves the right to fail for certain values. - @available(SwiftStdlib 5.9, *) + @available(StdlibDeploymentTarget 5.9, *) public init?(_ p: JobPriority) { guard p.rawValue != 0 else { // 0 is "undefined" diff --git a/stdlib/public/Concurrency/PriorityQueue.swift b/stdlib/public/Concurrency/PriorityQueue.swift index 744c9c4c257a2..b3839167ae823 100644 --- a/stdlib/public/Concurrency/PriorityQueue.swift +++ b/stdlib/public/Concurrency/PriorityQueue.swift @@ -40,6 +40,15 @@ struct PriorityQueue { self.compare = compare } + /// Take the queue. + /// + /// This returns a copy of the queue, and empties the original. + mutating func take() -> PriorityQueue { + var q = PriorityQueue(compare: self.compare) + swap(&self, &q) + return q + } + /// Push an item onto the queue. /// /// Parameters: @@ -51,6 +60,11 @@ struct PriorityQueue { upHeap(ndx: storage.count - 1) } + /// Return `true` if the queue is empty + var isEmpty: Bool { + return storage.isEmpty + } + /// The highest priority item from the queue, or `nil` if none. var top: T? { if storage.isEmpty { diff --git a/stdlib/public/Concurrency/SuspendingClock.swift b/stdlib/public/Concurrency/SuspendingClock.swift index e07c3cc90a094..12d0a5e361e96 100644 --- a/stdlib/public/Concurrency/SuspendingClock.swift +++ b/stdlib/public/Concurrency/SuspendingClock.swift @@ -179,3 +179,36 @@ extension SuspendingClock.Instant: InstantProtocol { rhs.duration(to: lhs) } } + +#if !$Embedded && !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY +@available(StdlibDeploymentTarget 6.2, *) +extension SuspendingClock { + + public func run(_ job: consuming ExecutorJob, + at instant: Instant, + tolerance: Duration?) { + guard let executor = Task.currentSchedulingExecutor else { + fatalError("no scheduling executor is available") + } + + executor.enqueue(job, at: instant, + tolerance: tolerance, + clock: self) + } + + public func enqueue(_ job: consuming ExecutorJob, + on executor: some Executor, + at instant: Instant, + tolerance: Duration?) { + if let schedulingExecutor = executor.asSchedulingExecutor { + schedulingExecutor.enqueue(job, at: instant, + tolerance: tolerance, + clock: self) + } else { + let trampoline = job.createTrampoline(to: executor) + run(trampoline, at: instant, tolerance: tolerance) + } + } + +} +#endif diff --git a/stdlib/public/Concurrency/TaskSleep.swift b/stdlib/public/Concurrency/TaskSleep.swift index c40483bfb4a70..b9994e01698eb 100644 --- a/stdlib/public/Concurrency/TaskSleep.swift +++ b/stdlib/public/Concurrency/TaskSleep.swift @@ -30,7 +30,7 @@ extension Task where Success == Never, Failure == Never { if #available(StdlibDeploymentTarget 6.2, *) { #if !$Embedded - if let executor = Task.currentSchedulableExecutor { + if let executor = Task.currentSchedulingExecutor { executor.enqueue(ExecutorJob(context: job), after: .nanoseconds(duration), clock: .continuous) @@ -39,7 +39,7 @@ extension Task where Success == Never, Failure == Never { #endif } - // If there is no current schedulable executor, fall back to + // If there is no current scheduling executor, fall back to // _enqueueJobGlobalWithDelay() _enqueueJobGlobalWithDelay(duration, job) } @@ -274,7 +274,7 @@ extension Task where Success == Never, Failure == Never { if #available(StdlibDeploymentTarget 6.2, *) { #if !$Embedded - if let executor = Task.currentSchedulableExecutor { + if let executor = Task.currentSchedulingExecutor { executor.enqueue(ExecutorJob(context: job), after: .nanoseconds(duration), clock: .continuous) @@ -283,7 +283,7 @@ extension Task where Success == Never, Failure == Never { #endif } - // If there is no current schedulable executor, fall back to + // If there is no current scheduling executor, fall back to // _enqueueJobGlobalWithDelay() _enqueueJobGlobalWithDelay(duration, job) return diff --git a/stdlib/public/Concurrency/TaskSleepDuration.swift b/stdlib/public/Concurrency/TaskSleepDuration.swift index 0add81810773d..27f35eb321b7c 100644 --- a/stdlib/public/Concurrency/TaskSleepDuration.swift +++ b/stdlib/public/Concurrency/TaskSleepDuration.swift @@ -13,46 +13,64 @@ import Swift #if !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY -@available(StdlibDeploymentTarget 5.7, *) -fileprivate func timestamp(for instant: C.Instant, clock: C) - -> (clockID: _ClockID, seconds: Int64, nanoseconds: Int64) { - var clockID: _ClockID - #if $Embedded - clockID = .suspending - #else - if #available(StdlibDeploymentTarget 6.2, *) { - if clock is ContinuousClock { - clockID = .continuous - } else { - clockID = .suspending - } - } else { - fatalError("we shouldn't get here; if we have, availability is broken") +@_unavailableInEmbedded +extension ContinuousClock { + func timestamp(for instant: Instant) + -> (clockID: _ClockID, seconds: Int64, nanoseconds: Int64) + { + let (seconds, nanoseconds) = durationComponents(for: instant._value) + return (clockID: .continuous, seconds: seconds, nanoseconds: nanoseconds) } - #endif - var seconds: Int64 = 0 - var nanoseconds: Int64 = 0 - unsafe _getTime(seconds: &seconds, - nanoseconds: &nanoseconds, - clock: clockID.rawValue) + func durationComponents(for duration: Duration) + -> (seconds: Int64, nanoseconds: Int64) + { + let (seconds, attoseconds) = duration.components + let nanoseconds = attoseconds / 1_000_000_000 + return (seconds: seconds, nanoseconds: nanoseconds) + } +} + +@_unavailableInEmbedded +extension SuspendingClock { + func timestamp(for instant: Instant) + -> (clockID: _ClockID, seconds: Int64, nanoseconds: Int64) + { + let (seconds, nanoseconds) = durationComponents(for: instant._value) + return (clockID: .suspending, seconds: seconds, nanoseconds: nanoseconds) + } - guard let delta = clock.now.duration(to: instant) as? Swift.Duration else { - fatalError("Unsupported clock") + func durationComponents(for duration: Duration) + -> (seconds: Int64, nanoseconds: Int64) + { + let (seconds, attoseconds) = duration.components + let nanoseconds = attoseconds / 1_000_000_000 + return (seconds: seconds, nanoseconds: nanoseconds) } +} - let (deltaSeconds, deltaAttoseconds) = delta.components - let deltaNanoseconds = deltaAttoseconds / 1_000_000_000 - seconds += deltaSeconds - nanoseconds += deltaNanoseconds - if nanoseconds > 1_000_000_000 { - seconds += 1 - nanoseconds -= 1_000_000_000 +fileprivate func timestamp(for instant: C.Instant, clock: C) + -> (clockID: _ClockID, seconds: Int64, nanoseconds: Int64) { + #if !$Embedded + if let continuousClock = clock as? ContinuousClock { + return continuousClock.timestamp(for: instant as! ContinuousClock.Instant) + } else if let suspendingClock = clock as? SuspendingClock { + return suspendingClock.timestamp(for: instant as! SuspendingClock.Instant) } + #endif + fatalError("unknown clock in fallback path") +} - return (clockID: clockID, - seconds: Int64(seconds), - nanoseconds: Int64(nanoseconds)) +fileprivate func durationComponents(for duration: C.Duration, clock: C) + -> (seconds: Int64, nanoseconds: Int64) { + #if !$Embedded + if let continuousClock = clock as? ContinuousClock { + return continuousClock.durationComponents(for: duration as! ContinuousClock.Duration) + } else if let suspendingClock = clock as? SuspendingClock { + return suspendingClock.durationComponents(for: duration as! SuspendingClock.Duration) + } + #endif + fatalError("unknown clock in fallback path") } @available(StdlibDeploymentTarget 5.7, *) @@ -100,7 +118,7 @@ extension Task where Success == Never, Failure == Never { if #available(StdlibDeploymentTarget 6.2, *) { #if !$Embedded - if let executor = Task.currentSchedulableExecutor { + if let executor = Task.currentSchedulingExecutor { executor.enqueue(ExecutorJob(context: job), at: instant, tolerance: tolerance, @@ -112,17 +130,16 @@ extension Task where Success == Never, Failure == Never { fatalError("we shouldn't get here; if we have, availability is broken") } - // If there is no current schedulable executor, fall back to + // If there is no current scheduling executor, fall back to // calling _enqueueJobGlobalWithDeadline(). let (clockID, seconds, nanoseconds) = timestamp(for: instant, clock: clock) let toleranceSeconds: Int64 let toleranceNanoseconds: Int64 if #available(StdlibDeploymentTarget 6.2, *) { - if let tolerance = tolerance as? Swift.Duration { - let components = tolerance.components - toleranceSeconds = components.seconds - toleranceNanoseconds = components.attoseconds / 1_000_000_000 + if let tolerance = tolerance { + (toleranceSeconds, toleranceNanoseconds) + = durationComponents(for: tolerance, clock: clock) } else { toleranceSeconds = 0 toleranceNanoseconds = -1 diff --git a/test/abi/Inputs/macOS/arm64/concurrency/baseline b/test/abi/Inputs/macOS/arm64/concurrency/baseline index c6893523ad290..8833498aa2dc4 100644 --- a/test/abi/Inputs/macOS/arm64/concurrency/baseline +++ b/test/abi/Inputs/macOS/arm64/concurrency/baseline @@ -399,6 +399,7 @@ _$ss11ExecutorJobV14LocalAllocatorV8allocate8capacitySwSi_tF _$ss11ExecutorJobV14LocalAllocatorVMa _$ss11ExecutorJobV14LocalAllocatorVMn _$ss11ExecutorJobV14LocalAllocatorVN +_$ss11ExecutorJobV16createTrampoline2toABx_tScFRzlF _$ss11ExecutorJobV4KindV13firstReservedADvgZ _$ss11ExecutorJobV4KindV13firstReservedADvpZMV _$ss11ExecutorJobV4KindV4taskADvgZ @@ -454,6 +455,7 @@ _$ss15ContinuousClockV17minimumResolutions8DurationVvpMV _$ss15ContinuousClockV3nowAB7InstantVvg _$ss15ContinuousClockV3nowAB7InstantVvgZ _$ss15ContinuousClockV3nowAB7InstantVvpMV +_$ss15ContinuousClockV3run_2at9toleranceys11ExecutorJobVn_AB7InstantVs8DurationVSgtF _$ss15ContinuousClockV5sleep5until9toleranceyAB7InstantV_s8DurationVSgtYaKF _$ss15ContinuousClockV5sleep5until9toleranceyAB7InstantV_s8DurationVSgtYaKFTu _$ss15ContinuousClockV7InstantV1loiySbAD_ADtFZ @@ -475,6 +477,7 @@ _$ss15ContinuousClockV7InstantVSLsMc _$ss15ContinuousClockV7InstantVSQsMc _$ss15ContinuousClockV7InstantVSesMc _$ss15ContinuousClockV7InstantVs0C8ProtocolsMc +_$ss15ContinuousClockV7enqueue_2on2at9toleranceys11ExecutorJobVn_xAB7InstantVs8DurationVSgtScFRzlF _$ss15ContinuousClockVABycfC _$ss15ContinuousClockVMa _$ss15ContinuousClockVMn @@ -486,6 +489,7 @@ _$ss15SuspendingClockV17minimumResolutions8DurationVvpMV _$ss15SuspendingClockV3nowAB7InstantVvg _$ss15SuspendingClockV3nowAB7InstantVvgZ _$ss15SuspendingClockV3nowAB7InstantVvpMV +_$ss15SuspendingClockV3run_2at9toleranceys11ExecutorJobVn_AB7InstantVs8DurationVSgtF _$ss15SuspendingClockV5sleep5until9toleranceyAB7InstantV_s8DurationVSgtYaKF _$ss15SuspendingClockV5sleep5until9toleranceyAB7InstantV_s8DurationVSgtYaKFTu _$ss15SuspendingClockV7InstantV1loiySbAD_ADtFZ @@ -512,6 +516,7 @@ _$ss15SuspendingClockV7InstantVSLsMc _$ss15SuspendingClockV7InstantVSQsMc _$ss15SuspendingClockV7InstantVSesMc _$ss15SuspendingClockV7InstantVs0C8ProtocolsMc +_$ss15SuspendingClockV7enqueue_2on2at9toleranceys11ExecutorJobVn_xAB7InstantVs8DurationVSgtScFRzlF _$ss15SuspendingClockVABycfC _$ss15SuspendingClockVMa _$ss15SuspendingClockVMn diff --git a/test/abi/Inputs/macOS/arm64/concurrency/baseline-asserts b/test/abi/Inputs/macOS/arm64/concurrency/baseline-asserts index c6893523ad290..8833498aa2dc4 100644 --- a/test/abi/Inputs/macOS/arm64/concurrency/baseline-asserts +++ b/test/abi/Inputs/macOS/arm64/concurrency/baseline-asserts @@ -399,6 +399,7 @@ _$ss11ExecutorJobV14LocalAllocatorV8allocate8capacitySwSi_tF _$ss11ExecutorJobV14LocalAllocatorVMa _$ss11ExecutorJobV14LocalAllocatorVMn _$ss11ExecutorJobV14LocalAllocatorVN +_$ss11ExecutorJobV16createTrampoline2toABx_tScFRzlF _$ss11ExecutorJobV4KindV13firstReservedADvgZ _$ss11ExecutorJobV4KindV13firstReservedADvpZMV _$ss11ExecutorJobV4KindV4taskADvgZ @@ -454,6 +455,7 @@ _$ss15ContinuousClockV17minimumResolutions8DurationVvpMV _$ss15ContinuousClockV3nowAB7InstantVvg _$ss15ContinuousClockV3nowAB7InstantVvgZ _$ss15ContinuousClockV3nowAB7InstantVvpMV +_$ss15ContinuousClockV3run_2at9toleranceys11ExecutorJobVn_AB7InstantVs8DurationVSgtF _$ss15ContinuousClockV5sleep5until9toleranceyAB7InstantV_s8DurationVSgtYaKF _$ss15ContinuousClockV5sleep5until9toleranceyAB7InstantV_s8DurationVSgtYaKFTu _$ss15ContinuousClockV7InstantV1loiySbAD_ADtFZ @@ -475,6 +477,7 @@ _$ss15ContinuousClockV7InstantVSLsMc _$ss15ContinuousClockV7InstantVSQsMc _$ss15ContinuousClockV7InstantVSesMc _$ss15ContinuousClockV7InstantVs0C8ProtocolsMc +_$ss15ContinuousClockV7enqueue_2on2at9toleranceys11ExecutorJobVn_xAB7InstantVs8DurationVSgtScFRzlF _$ss15ContinuousClockVABycfC _$ss15ContinuousClockVMa _$ss15ContinuousClockVMn @@ -486,6 +489,7 @@ _$ss15SuspendingClockV17minimumResolutions8DurationVvpMV _$ss15SuspendingClockV3nowAB7InstantVvg _$ss15SuspendingClockV3nowAB7InstantVvgZ _$ss15SuspendingClockV3nowAB7InstantVvpMV +_$ss15SuspendingClockV3run_2at9toleranceys11ExecutorJobVn_AB7InstantVs8DurationVSgtF _$ss15SuspendingClockV5sleep5until9toleranceyAB7InstantV_s8DurationVSgtYaKF _$ss15SuspendingClockV5sleep5until9toleranceyAB7InstantV_s8DurationVSgtYaKFTu _$ss15SuspendingClockV7InstantV1loiySbAD_ADtFZ @@ -512,6 +516,7 @@ _$ss15SuspendingClockV7InstantVSLsMc _$ss15SuspendingClockV7InstantVSQsMc _$ss15SuspendingClockV7InstantVSesMc _$ss15SuspendingClockV7InstantVs0C8ProtocolsMc +_$ss15SuspendingClockV7enqueue_2on2at9toleranceys11ExecutorJobVn_xAB7InstantVs8DurationVSgtScFRzlF _$ss15SuspendingClockVABycfC _$ss15SuspendingClockVMa _$ss15SuspendingClockVMn diff --git a/test/abi/Inputs/macOS/x86_64/concurrency/baseline b/test/abi/Inputs/macOS/x86_64/concurrency/baseline index c6893523ad290..8833498aa2dc4 100644 --- a/test/abi/Inputs/macOS/x86_64/concurrency/baseline +++ b/test/abi/Inputs/macOS/x86_64/concurrency/baseline @@ -399,6 +399,7 @@ _$ss11ExecutorJobV14LocalAllocatorV8allocate8capacitySwSi_tF _$ss11ExecutorJobV14LocalAllocatorVMa _$ss11ExecutorJobV14LocalAllocatorVMn _$ss11ExecutorJobV14LocalAllocatorVN +_$ss11ExecutorJobV16createTrampoline2toABx_tScFRzlF _$ss11ExecutorJobV4KindV13firstReservedADvgZ _$ss11ExecutorJobV4KindV13firstReservedADvpZMV _$ss11ExecutorJobV4KindV4taskADvgZ @@ -454,6 +455,7 @@ _$ss15ContinuousClockV17minimumResolutions8DurationVvpMV _$ss15ContinuousClockV3nowAB7InstantVvg _$ss15ContinuousClockV3nowAB7InstantVvgZ _$ss15ContinuousClockV3nowAB7InstantVvpMV +_$ss15ContinuousClockV3run_2at9toleranceys11ExecutorJobVn_AB7InstantVs8DurationVSgtF _$ss15ContinuousClockV5sleep5until9toleranceyAB7InstantV_s8DurationVSgtYaKF _$ss15ContinuousClockV5sleep5until9toleranceyAB7InstantV_s8DurationVSgtYaKFTu _$ss15ContinuousClockV7InstantV1loiySbAD_ADtFZ @@ -475,6 +477,7 @@ _$ss15ContinuousClockV7InstantVSLsMc _$ss15ContinuousClockV7InstantVSQsMc _$ss15ContinuousClockV7InstantVSesMc _$ss15ContinuousClockV7InstantVs0C8ProtocolsMc +_$ss15ContinuousClockV7enqueue_2on2at9toleranceys11ExecutorJobVn_xAB7InstantVs8DurationVSgtScFRzlF _$ss15ContinuousClockVABycfC _$ss15ContinuousClockVMa _$ss15ContinuousClockVMn @@ -486,6 +489,7 @@ _$ss15SuspendingClockV17minimumResolutions8DurationVvpMV _$ss15SuspendingClockV3nowAB7InstantVvg _$ss15SuspendingClockV3nowAB7InstantVvgZ _$ss15SuspendingClockV3nowAB7InstantVvpMV +_$ss15SuspendingClockV3run_2at9toleranceys11ExecutorJobVn_AB7InstantVs8DurationVSgtF _$ss15SuspendingClockV5sleep5until9toleranceyAB7InstantV_s8DurationVSgtYaKF _$ss15SuspendingClockV5sleep5until9toleranceyAB7InstantV_s8DurationVSgtYaKFTu _$ss15SuspendingClockV7InstantV1loiySbAD_ADtFZ @@ -512,6 +516,7 @@ _$ss15SuspendingClockV7InstantVSLsMc _$ss15SuspendingClockV7InstantVSQsMc _$ss15SuspendingClockV7InstantVSesMc _$ss15SuspendingClockV7InstantVs0C8ProtocolsMc +_$ss15SuspendingClockV7enqueue_2on2at9toleranceys11ExecutorJobVn_xAB7InstantVs8DurationVSgtScFRzlF _$ss15SuspendingClockVABycfC _$ss15SuspendingClockVMa _$ss15SuspendingClockVMn diff --git a/test/abi/Inputs/macOS/x86_64/concurrency/baseline-asserts b/test/abi/Inputs/macOS/x86_64/concurrency/baseline-asserts index c6893523ad290..8833498aa2dc4 100644 --- a/test/abi/Inputs/macOS/x86_64/concurrency/baseline-asserts +++ b/test/abi/Inputs/macOS/x86_64/concurrency/baseline-asserts @@ -399,6 +399,7 @@ _$ss11ExecutorJobV14LocalAllocatorV8allocate8capacitySwSi_tF _$ss11ExecutorJobV14LocalAllocatorVMa _$ss11ExecutorJobV14LocalAllocatorVMn _$ss11ExecutorJobV14LocalAllocatorVN +_$ss11ExecutorJobV16createTrampoline2toABx_tScFRzlF _$ss11ExecutorJobV4KindV13firstReservedADvgZ _$ss11ExecutorJobV4KindV13firstReservedADvpZMV _$ss11ExecutorJobV4KindV4taskADvgZ @@ -454,6 +455,7 @@ _$ss15ContinuousClockV17minimumResolutions8DurationVvpMV _$ss15ContinuousClockV3nowAB7InstantVvg _$ss15ContinuousClockV3nowAB7InstantVvgZ _$ss15ContinuousClockV3nowAB7InstantVvpMV +_$ss15ContinuousClockV3run_2at9toleranceys11ExecutorJobVn_AB7InstantVs8DurationVSgtF _$ss15ContinuousClockV5sleep5until9toleranceyAB7InstantV_s8DurationVSgtYaKF _$ss15ContinuousClockV5sleep5until9toleranceyAB7InstantV_s8DurationVSgtYaKFTu _$ss15ContinuousClockV7InstantV1loiySbAD_ADtFZ @@ -475,6 +477,7 @@ _$ss15ContinuousClockV7InstantVSLsMc _$ss15ContinuousClockV7InstantVSQsMc _$ss15ContinuousClockV7InstantVSesMc _$ss15ContinuousClockV7InstantVs0C8ProtocolsMc +_$ss15ContinuousClockV7enqueue_2on2at9toleranceys11ExecutorJobVn_xAB7InstantVs8DurationVSgtScFRzlF _$ss15ContinuousClockVABycfC _$ss15ContinuousClockVMa _$ss15ContinuousClockVMn @@ -486,6 +489,7 @@ _$ss15SuspendingClockV17minimumResolutions8DurationVvpMV _$ss15SuspendingClockV3nowAB7InstantVvg _$ss15SuspendingClockV3nowAB7InstantVvgZ _$ss15SuspendingClockV3nowAB7InstantVvpMV +_$ss15SuspendingClockV3run_2at9toleranceys11ExecutorJobVn_AB7InstantVs8DurationVSgtF _$ss15SuspendingClockV5sleep5until9toleranceyAB7InstantV_s8DurationVSgtYaKF _$ss15SuspendingClockV5sleep5until9toleranceyAB7InstantV_s8DurationVSgtYaKFTu _$ss15SuspendingClockV7InstantV1loiySbAD_ADtFZ @@ -512,6 +516,7 @@ _$ss15SuspendingClockV7InstantVSLsMc _$ss15SuspendingClockV7InstantVSQsMc _$ss15SuspendingClockV7InstantVSesMc _$ss15SuspendingClockV7InstantVs0C8ProtocolsMc +_$ss15SuspendingClockV7enqueue_2on2at9toleranceys11ExecutorJobVn_xAB7InstantVs8DurationVSgtScFRzlF _$ss15SuspendingClockVABycfC _$ss15SuspendingClockVMa _$ss15SuspendingClockVMn From ee536ce5a9f68208bff3995fec615199ec0f5048 Mon Sep 17 00:00:00 2001 From: Alastair Houghton Date: Wed, 27 Aug 2025 15:46:17 +0100 Subject: [PATCH 2/5] [Concurrency] Make all the new functionality public. This makes the custom global executor support and associated functionality public. --- include/swift/ABI/Task.h | 4 + stdlib/public/Concurrency/Clock.swift | 44 ++++++- .../Concurrency/DispatchGlobalExecutor.cpp | 4 +- stdlib/public/Concurrency/Executor.swift | 84 +++++++++---- stdlib/public/Concurrency/ExecutorBridge.cpp | 5 + stdlib/public/Concurrency/ExecutorBridge.h | 3 + .../public/Concurrency/ExecutorBridge.swift | 16 ++- .../public/Concurrency/PartialAsyncTask.swift | 49 ++++++-- .../PlatformExecutorCooperative.swift | 2 +- .../Concurrency/PlatformExecutorDarwin.swift | 2 +- .../Concurrency/PlatformExecutorFreeBSD.swift | 2 +- .../Concurrency/PlatformExecutorLinux.swift | 2 +- .../Concurrency/PlatformExecutorNone.swift | 2 +- .../Concurrency/PlatformExecutorOpenBSD.swift | 2 +- .../Concurrency/PlatformExecutorWindows.swift | 2 +- .../Concurrency/UnimplementedExecutor.swift | 4 +- .../Inputs/macOS/arm64/concurrency/baseline | 115 ++++++++++++++++++ .../macOS/arm64/concurrency/baseline-asserts | 115 ++++++++++++++++++ .../Inputs/macOS/x86_64/concurrency/baseline | 115 ++++++++++++++++++ .../macOS/x86_64/concurrency/baseline-asserts | 115 ++++++++++++++++++ 20 files changed, 636 insertions(+), 51 deletions(-) diff --git a/include/swift/ABI/Task.h b/include/swift/ABI/Task.h index 1961ec2514996..594f85c92bfbb 100644 --- a/include/swift/ABI/Task.h +++ b/include/swift/ABI/Task.h @@ -154,6 +154,10 @@ class alignas(2 * alignof(void*)) Job : return Flags.getPriority(); } + void setPriority(JobPriority priority) { + Flags.setPriority(priority); + } + uint32_t getJobId() const { return Id; } diff --git a/stdlib/public/Concurrency/Clock.swift b/stdlib/public/Concurrency/Clock.swift index 099ed1b5e2ce3..dd38cbcbadbe0 100644 --- a/stdlib/public/Concurrency/Clock.swift +++ b/stdlib/public/Concurrency/Clock.swift @@ -40,6 +40,40 @@ public protocol Clock: Sendable { #if !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY func sleep(until deadline: Instant, tolerance: Instant.Duration?) async throws + + /// Run the given job on an unspecified executor at some point + /// after the given instant. + /// + /// Parameters: + /// + /// - job: The job we wish to run + /// - at instant: The time at which we would like it to run. + /// - tolerance: The ideal maximum delay we are willing to tolerate. + /// + @available(StdlibDeploymentTarget 6.2, *) + func run(_ job: consuming ExecutorJob, + at instant: Instant, tolerance: Duration?) + + /// Enqueue the given job on the specified executor at some point after the + /// given instant. + /// + /// The default implementation uses the `run` method to trigger a job that + /// does `executor.enqueue(job)`. If a particular `Clock` knows that the + /// executor it has been asked to use is the same one that it will run jobs + /// on, it can short-circuit this behaviour and directly use `run` with + /// the original job. + /// + /// Parameters: + /// + /// - job: The job we wish to run + /// - on executor: The executor on which we would like it to run. + /// - at instant: The time at which we would like it to run. + /// - tolerance: The ideal maximum delay we are willing to tolerate. + /// + @available(StdlibDeploymentTarget 6.2, *) + func enqueue(_ job: consuming ExecutorJob, + on executor: some Executor, + at instant: Instant, tolerance: Duration?) #endif } @@ -48,9 +82,9 @@ extension Clock { // The default implementation works by creating a trampoline and calling // the run() method. @available(StdlibDeploymentTarget 6.2, *) - func enqueue(_ job: consuming ExecutorJob, - on executor: some Executor, - at instant: Instant, tolerance: Duration?) { + public func enqueue(_ job: consuming ExecutorJob, + on executor: some Executor, + at instant: Instant, tolerance: Duration?) { let trampoline = job.createTrampoline(to: executor) run(trampoline, at: instant, tolerance: tolerance) } @@ -58,8 +92,8 @@ extension Clock { // Clocks that do not implement run will fatalError() if you try to use // them with an executor that does not understand them. @available(StdlibDeploymentTarget 6.2, *) - func run(_ job: consuming ExecutorJob, - at instant: Instant, tolerance: Duration?) { + public func run(_ job: consuming ExecutorJob, + at instant: Instant, tolerance: Duration?) { fatalError("\(Self.self) does not implement run(_:at:tolerance:).") } } diff --git a/stdlib/public/Concurrency/DispatchGlobalExecutor.cpp b/stdlib/public/Concurrency/DispatchGlobalExecutor.cpp index b9a72e5ecab14..e377670296e41 100644 --- a/stdlib/public/Concurrency/DispatchGlobalExecutor.cpp +++ b/stdlib/public/Concurrency/DispatchGlobalExecutor.cpp @@ -333,7 +333,7 @@ void swift_dispatchEnqueueWithDeadline(bool global, } uint64_t deadline; - if (sec < 0 || sec == 0 && nsec < 0) + if (sec < 0 || (sec == 0 && nsec < 0)) deadline = 0; else if (__builtin_mul_overflow(sec, NSEC_PER_SEC, &deadline) || __builtin_add_overflow(nsec, deadline, &deadline)) { @@ -344,7 +344,7 @@ void swift_dispatchEnqueueWithDeadline(bool global, if (tnsec != -1) { uint64_t leeway; - if (tsec < 0 || tsec == 0 && tnsec < 0) + if (tsec < 0 || (tsec == 0 && tnsec < 0)) leeway = 0; else if (__builtin_mul_overflow(tsec, NSEC_PER_SEC, &leeway) || __builtin_add_overflow(tnsec, leeway, &leeway)) { diff --git a/stdlib/public/Concurrency/Executor.swift b/stdlib/public/Concurrency/Executor.swift index 07a4f80f5dc58..5c00ec4d614c6 100644 --- a/stdlib/public/Concurrency/Executor.swift +++ b/stdlib/public/Concurrency/Executor.swift @@ -36,10 +36,24 @@ public protocol Executor: AnyObject, Sendable { func enqueue(_ job: consuming ExecutorJob) #endif // !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY + #if !$Embedded + /// `true` if this is the main executor. + @available(StdlibDeploymentTarget 6.2, *) + var isMainExecutor: Bool { get } + + /// Return this executable as a SchedulingExecutor, or nil if that is + /// unsupported. + /// + /// 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, *) + var asSchedulingExecutor: (any SchedulingExecutor)? { get } + #endif } @available(StdlibDeploymentTarget 6.2, *) -protocol SchedulingExecutor: Executor { +public protocol SchedulingExecutor: Executor { #if !$Embedded && !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY @@ -58,6 +72,7 @@ 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, *) func enqueue(_ job: consuming ExecutorJob, after delay: C.Duration, tolerance: C.Duration?, @@ -77,6 +92,7 @@ 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, *) func enqueue(_ job: consuming ExecutorJob, at instant: C.Instant, tolerance: C.Duration?, @@ -113,7 +129,7 @@ extension Executor { /// own copy of this method, which will allow the compiler to avoid a /// potentially expensive runtime cast. @available(StdlibDeploymentTarget 6.2, *) - var asSchedulingExecutor: (any SchedulingExecutor)? { + public var asSchedulingExecutor: (any SchedulingExecutor)? { return self as? SchedulingExecutor } #endif @@ -136,7 +152,7 @@ extension Executor { #if !$Embedded @available(StdlibDeploymentTarget 6.2, *) - var isMainExecutor: Bool { false } + public var isMainExecutor: Bool { false } #endif } @@ -147,20 +163,22 @@ extension SchedulingExecutor { #if !$Embedded && !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY - func enqueue(_ job: consuming ExecutorJob, - after delay: C.Duration, - tolerance: C.Duration? = nil, - clock: C) { + @available(StdlibDeploymentTarget 6.2, *) + public func enqueue(_ job: consuming ExecutorJob, + after delay: C.Duration, + tolerance: C.Duration? = nil, + clock: C) { // If you crash here with a mutual recursion, it's because you didn't // implement one of these two functions enqueue(job, at: clock.now.advanced(by: delay), tolerance: tolerance, clock: clock) } - func enqueue(_ job: consuming ExecutorJob, - at instant: C.Instant, - tolerance: C.Duration? = nil, - clock: C) { + @available(StdlibDeploymentTarget 6.2, *) + public func enqueue(_ job: consuming ExecutorJob, + at instant: C.Instant, + tolerance: C.Duration? = nil, + clock: C) { // If you crash here with a mutual recursion, it's because you didn't // implement one of these two functions enqueue(job, after: clock.now.duration(to: instant), @@ -355,7 +373,7 @@ extension SerialExecutor { #if !$Embedded && !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY @available(StdlibDeploymentTarget 6.2, *) - var isMainExecutor: Bool { return MainActor.executor._isSameExecutor(self) } + public var isMainExecutor: Bool { return MainActor.executor._isSameExecutor(self) } #endif @available(StdlibDeploymentTarget 6.0, *) @@ -510,7 +528,8 @@ 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. -protocol RunLoopExecutor: Executor { +@available(StdlibDeploymentTarget 6.2, *) +public protocol RunLoopExecutor: Executor { /// Run the executor's run loop. /// /// This method will synchronously block the calling thread. Nested calls to @@ -540,9 +559,10 @@ protocol RunLoopExecutor: Executor { func stop() } +@available(StdlibDeploymentTarget 6.2, *) extension RunLoopExecutor { - func runUntil(_ condition: () -> Bool) throws { + public func runUntil(_ condition: () -> Bool) throws { fatalError("run(until condition:) not supported on this executor") } @@ -551,14 +571,15 @@ extension RunLoopExecutor { /// The main executor must conform to these two protocols; we have to /// make this a protocol for compatibility with Embedded Swift. -protocol MainExecutor: RunLoopExecutor, SerialExecutor { +@available(StdlibDeploymentTarget 6.2, *) +public protocol MainExecutor: RunLoopExecutor, SerialExecutor { } /// An ExecutorFactory is used to create the default main and task /// executors. @available(StdlibDeploymentTarget 6.2, *) -protocol ExecutorFactory { +public protocol ExecutorFactory { #if !$Embedded /// Constructs and returns the main executor, which is started implicitly /// by the `async main` entry point and owns the "main" thread. @@ -575,7 +596,7 @@ typealias DefaultExecutorFactory = PlatformExecutorFactory @available(StdlibDeploymentTarget 6.2, *) @_silgen_name("swift_createExecutors") -func _createExecutors(factory: F.Type) { +public func _createExecutors(factory: F.Type) { #if !$Embedded && !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY MainActor._executor = factory.mainExecutor #endif @@ -600,7 +621,8 @@ extension MainActor { /// /// Attempting to set this after the first `enqueue` on the main /// executor is a fatal error. - static var executor: any MainExecutor { + @available(StdlibDeploymentTarget 6.2, *) + public static var executor: any MainExecutor { // It would be good if there was a Swift way to do this _createDefaultExecutorsOnce() return _executor! @@ -624,11 +646,19 @@ extension Task where Success == Never, Failure == Never { /// /// Attempting to set this after the first `enqueue` on the global /// executor is a fatal error. - static var defaultExecutor: any TaskExecutor { + @available(StdlibDeploymentTarget 6.2, *) + public static var defaultExecutor: any TaskExecutor { // It would be good if there was a Swift way to do this _createDefaultExecutorsOnce() return _defaultExecutor! } + + /// An unowned version of the above, for performance + @available(StdlibDeploymentTarget 6.2, *) + static var unownedDefaultExecutor: UnownedTaskExecutor { + _createDefaultExecutorsOnce() + return unsafe UnownedTaskExecutor(_defaultExecutor!) + } } @available(StdlibDeploymentTarget 6.2, *) @@ -644,8 +674,9 @@ 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, *) @_unavailableInEmbedded - static var currentExecutor: any Executor { + public static var currentExecutor: any Executor { if let activeExecutor = unsafe _getActiveExecutor().asSerialExecutor() { return activeExecutor } else if let taskExecutor = unsafe _getPreferredTaskExecutor().asTaskExecutor() { @@ -657,7 +688,8 @@ extension Task where Success == Never, Failure == Never { } /// Get the preferred executor for the current `Task`, if any. - static var preferredExecutor: (any TaskExecutor)? { + @available(StdlibDeploymentTarget 6.2, *) + public static var preferredExecutor: (any TaskExecutor)? { if let taskExecutor = unsafe _getPreferredTaskExecutor().asTaskExecutor() { return taskExecutor } @@ -670,7 +702,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, *) - static var currentSchedulingExecutor: (any SchedulingExecutor)? { + public static var currentSchedulingExecutor: (any SchedulingExecutor)? { if let activeExecutor = unsafe _getActiveExecutor().asSerialExecutor(), let scheduling = activeExecutor.asSchedulingExecutor { return scheduling @@ -762,7 +794,8 @@ public struct UnownedSerialExecutor: Sendable { unsafe _executor_isComplexEquality(self) } - func asSerialExecutor() -> (any SerialExecutor)? { + @available(StdlibDeploymentTarget 6.2, *) + public func asSerialExecutor() -> (any SerialExecutor)? { return unsafe unsafeBitCast(executor, to: (any SerialExecutor)?.self) } } @@ -792,13 +825,14 @@ public struct UnownedTaskExecutor: Sendable { unsafe self.executor = Builtin.buildOrdinaryTaskExecutorRef(executor) } - @available(SwiftStdlib 6.2, *) + @available(StdlibDeploymentTarget 6.2, *) @inlinable public init(_ executor: __shared E) { unsafe self.executor = Builtin.buildOrdinaryTaskExecutorRef(executor) } - func asTaskExecutor() -> (any TaskExecutor)? { + @available(StdlibDeploymentTarget 6.2, *) + public func asTaskExecutor() -> (any TaskExecutor)? { return unsafe unsafeBitCast(executor, to: (any TaskExecutor)?.self) } } diff --git a/stdlib/public/Concurrency/ExecutorBridge.cpp b/stdlib/public/Concurrency/ExecutorBridge.cpp index 9838ad068b749..f5cb5a8280401 100644 --- a/stdlib/public/Concurrency/ExecutorBridge.cpp +++ b/stdlib/public/Concurrency/ExecutorBridge.cpp @@ -54,6 +54,11 @@ uint8_t swift_job_getPriority(Job *job) { return (uint8_t)(job->getPriority()); } +extern "C" SWIFT_CC(swift) +void swift_job_setPriority(Job *job, uint8_t priority) { + job->setPriority(JobPriority(priority)); +} + extern "C" SWIFT_CC(swift) uint8_t swift_job_getKind(Job *job) { return (uint8_t)(job->Flags.getKind()); diff --git a/stdlib/public/Concurrency/ExecutorBridge.h b/stdlib/public/Concurrency/ExecutorBridge.h index 3a65c075dbc55..1849495dc6498 100644 --- a/stdlib/public/Concurrency/ExecutorBridge.h +++ b/stdlib/public/Concurrency/ExecutorBridge.h @@ -23,6 +23,9 @@ namespace swift { extern "C" SWIFT_CC(swift) SerialExecutorRef swift_getMainExecutor(); +extern "C" SWIFT_CC(swift) +TaskExecutorRef swift_getDefaultExecutor(); + #if !SWIFT_CONCURRENCY_EMBEDDED extern "C" SWIFT_CC(swift) void *swift_createDispatchEventC(void (*handler)(void *), void *context); diff --git a/stdlib/public/Concurrency/ExecutorBridge.swift b/stdlib/public/Concurrency/ExecutorBridge.swift index 033dc98aa0973..65f45ce692c65 100644 --- a/stdlib/public/Concurrency/ExecutorBridge.swift +++ b/stdlib/public/Concurrency/ExecutorBridge.swift @@ -77,6 +77,10 @@ internal func _jobDeallocate(_ job: Builtin.Job, @_silgen_name("swift_job_getPriority") internal func _jobGetPriority(_ job: Builtin.Job) -> UInt8 +@available(StdlibDeploymentTarget 6.2, *) +@_silgen_name("swift_job_setPriority") +internal func _jobSetPriority(_ job: Builtin.Job, _ priority: UInt8) + @available(StdlibDeploymentTarget 6.2, *) @_silgen_name("swift_job_getKind") internal func _jobGetKind(_ job: Builtin.Job) -> UInt8 @@ -102,6 +106,12 @@ internal func _getMainExecutorAsSerialExecutor() -> UnownedSerialExecutor #endif // SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY #endif // !$Embedded +@available(StdlibDeploymentTarget 6.2, *) +@_silgen_name("swift_getDefaultExecutor") +internal func _getDefaultExecutorAsTaskExecutor() -> UnownedTaskExecutor { + return unsafe Task.unownedDefaultExecutor +} + @available(StdlibDeploymentTarget 6.2, *) @_silgen_name("swift_dispatchMain") internal func _dispatchMain() @@ -128,10 +138,10 @@ internal func _dispatchEnqueueWithDeadline(_ global: CBool, @_silgen_name("swift_dispatchAssertMainQueue") internal func _dispatchAssertMainQueue() +@_silgen_name("swift_createDefaultExecutorsOnce") +func _createDefaultExecutorsOnce() + @_silgen_name("swift_getDispatchQueueForExecutor") internal func _getDispatchQueueForExecutor( _ executor: UnownedSerialExecutor ) -> OpaquePointer? - -@_silgen_name("swift_createDefaultExecutorsOnce") -func _createDefaultExecutorsOnce() diff --git a/stdlib/public/Concurrency/PartialAsyncTask.swift b/stdlib/public/Concurrency/PartialAsyncTask.swift index 1a1a69cf5145e..7871e106df0f9 100644 --- a/stdlib/public/Concurrency/PartialAsyncTask.swift +++ b/stdlib/public/Concurrency/PartialAsyncTask.swift @@ -298,14 +298,23 @@ public struct ExecutorJob: Sendable, ~Copyable { self.context = job.context } - public var priority: JobPriority { - let raw: UInt8 - if #available(StdlibDeploymentTarget 6.2, *) { - raw = _jobGetPriority(self.context) - } else { - fatalError("we shouldn't get here; if we have, availability is broken") + internal(set) public var priority: JobPriority { + get { + let raw: UInt8 + if #available(StdlibDeploymentTarget 6.2, *) { + raw = _jobGetPriority(self.context) + } else { + fatalError("we shouldn't get here; if we have, availability is broken") + } + return JobPriority(rawValue: raw) + } + set { + if #available(StdlibDeploymentTarget 6.2, *) { + _jobSetPriority(self.context, newValue.rawValue) + } else { + fatalError("we shouldn't get here; if we have, availability is broken") + } } - return JobPriority(rawValue: raw) } /// Execute a closure, passing it the bounds of the executor private data @@ -580,6 +589,16 @@ public struct JobPriority: Sendable { /// The raw priority value. public var rawValue: RawValue + + /// Construct from a raw value + public init(rawValue: RawValue) { + self.rawValue = rawValue + } + + /// Construct from a TaskPriority + public init(_ p: TaskPriority) { + self.rawValue = p.rawValue + } } @available(StdlibDeploymentTarget 5.9, *) @@ -949,3 +968,19 @@ public func _unsafeInheritExecutor_withUnsafeThrowingContinuation( public func _abiEnableAwaitContinuation() { fatalError("never use this function") } + +#if !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY +@available(StdlibDeploymentTarget 6.2, *) +@_silgen_name("_swift_createJobForTestingOnly") +public func _swift_createJobForTestingOnly( + priority: TaskPriority = TaskPriority.medium, + _ body: @escaping () -> () +) -> ExecutorJob { + let flags: Int = Int(priority.rawValue) + let (task, _) = Builtin.createAsyncTask(flags, body) + var job = ExecutorJob(unsafe unsafeBitCast(Builtin.convertTaskToJob(task), + to: UnownedJob.self)) + job.priority = JobPriority(priority) + return job +} +#endif diff --git a/stdlib/public/Concurrency/PlatformExecutorCooperative.swift b/stdlib/public/Concurrency/PlatformExecutorCooperative.swift index 948ced93650a5..e9288bfc7cdd7 100644 --- a/stdlib/public/Concurrency/PlatformExecutorCooperative.swift +++ b/stdlib/public/Concurrency/PlatformExecutorCooperative.swift @@ -14,7 +14,7 @@ import Swift // This platform uses a single, global, CooperativeExecutor @available(StdlibDeploymentTarget 6.2, *) -struct PlatformExecutorFactory: ExecutorFactory { +public struct PlatformExecutorFactory: ExecutorFactory { static let executor = CooperativeExecutor() public static var mainExecutor: any MainExecutor { executor } public static var defaultExecutor: any TaskExecutor { executor } diff --git a/stdlib/public/Concurrency/PlatformExecutorDarwin.swift b/stdlib/public/Concurrency/PlatformExecutorDarwin.swift index 79758a37a4db6..71cf93d92f879 100644 --- a/stdlib/public/Concurrency/PlatformExecutorDarwin.swift +++ b/stdlib/public/Concurrency/PlatformExecutorDarwin.swift @@ -15,7 +15,7 @@ import Swift @available(StdlibDeploymentTarget 6.2, *) -struct PlatformExecutorFactory: ExecutorFactory { +public struct PlatformExecutorFactory: ExecutorFactory { public static var mainExecutor: any MainExecutor { if CoreFoundation.isPresent { return CFMainExecutor() diff --git a/stdlib/public/Concurrency/PlatformExecutorFreeBSD.swift b/stdlib/public/Concurrency/PlatformExecutorFreeBSD.swift index e6e7118edfc6a..b7a4deb25356c 100644 --- a/stdlib/public/Concurrency/PlatformExecutorFreeBSD.swift +++ b/stdlib/public/Concurrency/PlatformExecutorFreeBSD.swift @@ -16,7 +16,7 @@ import Swift // The default executors for now are Dispatch-based @available(SwiftStdlib 6.2, *) -struct PlatformExecutorFactory: ExecutorFactory { +public struct PlatformExecutorFactory: ExecutorFactory { public static let mainExecutor: any MainExecutor = DispatchMainExecutor() public static let defaultExecutor: any TaskExecutor = DispatchGlobalTaskExecutor() diff --git a/stdlib/public/Concurrency/PlatformExecutorLinux.swift b/stdlib/public/Concurrency/PlatformExecutorLinux.swift index 6b7fdfb9eb8e4..19d245a1a7e6e 100644 --- a/stdlib/public/Concurrency/PlatformExecutorLinux.swift +++ b/stdlib/public/Concurrency/PlatformExecutorLinux.swift @@ -16,7 +16,7 @@ import Swift // The default executors for now are Dispatch-based @available(StdlibDeploymentTarget 6.2, *) -struct PlatformExecutorFactory: ExecutorFactory { +public struct PlatformExecutorFactory: ExecutorFactory { public static let mainExecutor: any MainExecutor = DispatchMainExecutor() public static let defaultExecutor: any TaskExecutor = DispatchGlobalTaskExecutor() diff --git a/stdlib/public/Concurrency/PlatformExecutorNone.swift b/stdlib/public/Concurrency/PlatformExecutorNone.swift index 2aa5d48682204..c052893f5413a 100644 --- a/stdlib/public/Concurrency/PlatformExecutorNone.swift +++ b/stdlib/public/Concurrency/PlatformExecutorNone.swift @@ -13,7 +13,7 @@ import Swift @available(StdlibDeploymentTarget 6.2, *) -struct PlatformExecutorFactory: ExecutorFactory { +public struct PlatformExecutorFactory: ExecutorFactory { public static let mainExecutor: any MainExecutor = UnimplementedMainExecutor() public static let defaultExecutor: any TaskExecutor = UnimplementedTaskExecutor() } diff --git a/stdlib/public/Concurrency/PlatformExecutorOpenBSD.swift b/stdlib/public/Concurrency/PlatformExecutorOpenBSD.swift index b26135c527573..4bd2db9d5ebdc 100644 --- a/stdlib/public/Concurrency/PlatformExecutorOpenBSD.swift +++ b/stdlib/public/Concurrency/PlatformExecutorOpenBSD.swift @@ -16,7 +16,7 @@ import Swift // The default executors for now are Dispatch-based @available(SwiftStdlib 6.2, *) -struct PlatformExecutorFactory: ExecutorFactory { +public struct PlatformExecutorFactory: ExecutorFactory { public static let mainExecutor: any MainExecutor = DispatchMainExecutor() public static let defaultExecutor: any TaskExecutor = DispatchGlobalTaskExecutor() diff --git a/stdlib/public/Concurrency/PlatformExecutorWindows.swift b/stdlib/public/Concurrency/PlatformExecutorWindows.swift index d8e09f184b70e..08ec70519931c 100644 --- a/stdlib/public/Concurrency/PlatformExecutorWindows.swift +++ b/stdlib/public/Concurrency/PlatformExecutorWindows.swift @@ -16,7 +16,7 @@ import Swift // The default executors for now are Dispatch-based @available(StdlibDeploymentTarget 6.2, *) -struct PlatformExecutorFactory: ExecutorFactory { +public struct PlatformExecutorFactory: ExecutorFactory { public static let mainExecutor: any MainExecutor = DispatchMainExecutor() public static let defaultExecutor: any TaskExecutor = DispatchGlobalTaskExecutor() diff --git a/stdlib/public/Concurrency/UnimplementedExecutor.swift b/stdlib/public/Concurrency/UnimplementedExecutor.swift index 686bc146f2b47..f4a299fc550be 100644 --- a/stdlib/public/Concurrency/UnimplementedExecutor.swift +++ b/stdlib/public/Concurrency/UnimplementedExecutor.swift @@ -15,7 +15,7 @@ import Swift // .. Main Executor ............................................................ @available(StdlibDeploymentTarget 6.2, *) -final class UnimplementedMainExecutor: MainExecutor, @unchecked Sendable { +public final class UnimplementedMainExecutor: MainExecutor, @unchecked Sendable { public init() {} public func run() throws { @@ -46,7 +46,7 @@ final class UnimplementedMainExecutor: MainExecutor, @unchecked Sendable { // .. Task Executor ............................................................ @available(StdlibDeploymentTarget 6.2, *) -final class UnimplementedTaskExecutor: TaskExecutor, @unchecked Sendable { +public final class UnimplementedTaskExecutor: TaskExecutor, @unchecked Sendable { public init() {} #if SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY diff --git a/test/abi/Inputs/macOS/arm64/concurrency/baseline b/test/abi/Inputs/macOS/arm64/concurrency/baseline index 8833498aa2dc4..9f91995fd1839 100644 --- a/test/abi/Inputs/macOS/arm64/concurrency/baseline +++ b/test/abi/Inputs/macOS/arm64/concurrency/baseline @@ -23,6 +23,10 @@ _$sScEMa _$sScEMn _$sScEN _$sScEs5ErrorsMc +_$sScF14isMainExecutorSbvgTj +_$sScF14isMainExecutorSbvgTq +_$sScF20asSchedulingExecutors0bC0_pSgvgTj +_$sScF20asSchedulingExecutors0bC0_pSgvgTq _$sScF7enqueueyyScJFTj _$sScF7enqueueyyScJFTq _$sScF7enqueueyys11ExecutorJobVnFTj @@ -31,8 +35,12 @@ _$sScF7enqueueyys3JobVnFTj _$sScF7enqueueyys3JobVnFTq _$sScFMp _$sScFTL +_$sScFsE14isMainExecutorSbvg +_$sScFsE14isMainExecutorSbvpMV _$sScFsE18_isComplexEqualitySbvg _$sScFsE18_isComplexEqualitySbvpMV +_$sScFsE20asSchedulingExecutors0bC0_pSgvg +_$sScFsE20asSchedulingExecutors0bC0_pSgvpMV _$sScFsE7enqueueyyScJF _$sScFsE7enqueueyys11ExecutorJobVnF _$sScFsE7enqueueyys3JobVnF @@ -92,6 +100,8 @@ _$sScM3run10resultType4bodyxxm_xyYbKScMYcXEtYaKlFZ _$sScM3run10resultType4bodyxxm_xyYbKScMYcXEtYaKlFZTu _$sScM6sharedScMvgZ _$sScM7enqueueyyScJF +_$sScM8executors12MainExecutor_pvgZ +_$sScM8executors12MainExecutor_pvpZMV _$sScMMa _$sScMMm _$sScMMn @@ -205,8 +215,16 @@ _$sScTss5NeverORs_rlE5valuexvgTu _$sScTss5NeverORs_rlE5valuexvpMV _$sScTss5NeverORszABRs_rlE11isCancelledSbvgZ _$sScTss5NeverORszABRs_rlE12basePriorityScPSgvgZ +_$sScTss5NeverORszABRs_rlE15currentExecutorScF_pvgZ +_$sScTss5NeverORszABRs_rlE15currentExecutorScF_pvpZMV _$sScTss5NeverORszABRs_rlE15currentPriorityScPvgZ +_$sScTss5NeverORszABRs_rlE15defaultExecutorSch_pvgZ +_$sScTss5NeverORszABRs_rlE15defaultExecutorSch_pvpZMV _$sScTss5NeverORszABRs_rlE17checkCancellationyyKFZ +_$sScTss5NeverORszABRs_rlE17preferredExecutorSch_pSgvgZ +_$sScTss5NeverORszABRs_rlE17preferredExecutorSch_pSgvpZMV +_$sScTss5NeverORszABRs_rlE25currentSchedulingExecutors0cD0_pSgvgZ +_$sScTss5NeverORszABRs_rlE25currentSchedulingExecutors0cD0_pSgvpZMV _$sScTss5NeverORszABRs_rlE5sleep11nanosecondsys6UInt64V_tYaKFZ _$sScTss5NeverORszABRs_rlE5sleep11nanosecondsys6UInt64V_tYaKFZTu _$sScTss5NeverORszABRs_rlE5sleep5until9tolerance5clocky7InstantQyd___8DurationQyd__Sgqd__tYaKs5ClockRd__lFZ @@ -224,6 +242,7 @@ _$sScc7contextBcvs _$sSccMa _$sSccMn _$sSce15complexEqualityScexh_tcScfRzlufC +_$sSce16asSerialExecutorScf_pSgyF _$sSce18_isComplexEqualitySbvg _$sSce18_isComplexEqualitySbvpMV _$sSce8executorBevM @@ -252,6 +271,8 @@ _$sScfMp _$sScfScFTb _$sScfTL _$sScfsE14assertIsolated_4file4lineySSyXK_s12StaticStringVSutF +_$sScfsE14isMainExecutorSbvg +_$sScfsE14isMainExecutorSbvpMV _$sScfsE20preconditionIsolated_4file4lineySSyXK_s12StaticStringVSutF _$sScfsE23asUnownedSerialExecutorSceyF _$sScfsE31isSameExclusiveExecutionContext5otherSbx_tF @@ -438,6 +459,7 @@ _$ss11JobPriorityV2eeoiySbAB_ABtFZ _$ss11JobPriorityV2geoiySbAB_ABtFZ _$ss11JobPriorityV2leoiySbAB_ABtFZ _$ss11JobPriorityV2neoiySbAB_ABtFZ +_$ss11JobPriorityV8rawValueABs5UInt8V_tcfC _$ss11JobPriorityV8rawValues5UInt8VvM _$ss11JobPriorityV8rawValues5UInt8Vvg _$ss11JobPriorityV8rawValues5UInt8VvpMV @@ -447,6 +469,11 @@ _$ss11JobPriorityVMn _$ss11JobPriorityVN _$ss11JobPriorityVSLsMc _$ss11JobPriorityVSQsMc +_$ss11JobPriorityVyABScPcfC +_$ss12MainExecutorMp +_$ss12MainExecutorPScfTb +_$ss12MainExecutorPs07RunLoopB0Tb +_$ss12MainExecutorTL _$ss13_runAsyncMainyyyyYaKcF _$ss13withTaskGroup2of9returning4bodyq_xm_q_mq_ScGyxGzYaXEtYar0_lF _$ss13withTaskGroup2of9returning4bodyq_xm_q_mq_ScGyxGzYaXEtYar0_lFTu @@ -484,6 +511,22 @@ _$ss15ContinuousClockVMn _$ss15ContinuousClockVN _$ss15ContinuousClockVs0B0sMc _$ss15ContinuousClockVs0B0sWP +_$ss15ExecutorFactoryMp +_$ss15ExecutorFactoryP04mainA0s04MainA0_pvgZTj +_$ss15ExecutorFactoryP04mainA0s04MainA0_pvgZTq +_$ss15ExecutorFactoryP07defaultA0Sch_pvgZTj +_$ss15ExecutorFactoryP07defaultA0Sch_pvgZTq +_$ss15ExecutorFactoryTL +_$ss15RunLoopExecutorMp +_$ss15RunLoopExecutorP3runyyKFTj +_$ss15RunLoopExecutorP3runyyKFTq +_$ss15RunLoopExecutorP4stopyyFTj +_$ss15RunLoopExecutorP4stopyyFTq +_$ss15RunLoopExecutorP8runUntilyySbyXEKFTj +_$ss15RunLoopExecutorP8runUntilyySbyXEKFTq +_$ss15RunLoopExecutorPScFTb +_$ss15RunLoopExecutorPsE8runUntilyySbyXEKF +_$ss15RunLoopExecutorTL _$ss15SuspendingClockV17minimumResolutions8DurationVvg _$ss15SuspendingClockV17minimumResolutions8DurationVvpMV _$ss15SuspendingClockV3nowAB7InstantVvg @@ -544,6 +587,15 @@ _$ss16AsyncMapSequenceVMa _$ss16AsyncMapSequenceVMn _$ss16AsyncMapSequenceV_9transformAByxq_Gx_q_7ElementQzYactcfC _$ss16AsyncMapSequenceVyxq_GScisMc +_$ss18SchedulingExecutorMp +_$ss18SchedulingExecutorP7enqueue_2at9tolerance5clockys0B3JobVn_7InstantQyd__8DurationQyd__Sgqd__ts5ClockRd__lFTj +_$ss18SchedulingExecutorP7enqueue_2at9tolerance5clockys0B3JobVn_7InstantQyd__8DurationQyd__Sgqd__ts5ClockRd__lFTq +_$ss18SchedulingExecutorP7enqueue_5after9tolerance5clockys0B3JobVn_8DurationQyd__AJSgqd__ts5ClockRd__lFTj +_$ss18SchedulingExecutorP7enqueue_5after9tolerance5clockys0B3JobVn_8DurationQyd__AJSgqd__ts5ClockRd__lFTq +_$ss18SchedulingExecutorPScFTb +_$ss18SchedulingExecutorPsE7enqueue_2at9tolerance5clockys0B3JobVn_7InstantQyd__8DurationQyd__Sgqd__ts5ClockRd__lF +_$ss18SchedulingExecutorPsE7enqueue_5after9tolerance5clockys0B3JobVn_8DurationQyd__AJSgqd__ts5ClockRd__lF +_$ss18SchedulingExecutorTL _$ss19AsyncFilterSequenceV04makeA8IteratorAB0E0Vyx_GyF _$ss19AsyncFilterSequenceV10isIncludedySb7ElementQzYacvg _$ss19AsyncFilterSequenceV10isIncludedySb7ElementQzYacvpMV @@ -601,6 +653,7 @@ _$ss19DiscardingTaskGroupV9cancelAllyyF _$ss19DiscardingTaskGroupVMa _$ss19DiscardingTaskGroupVMn _$ss19DiscardingTaskGroupVN +_$ss19UnownedTaskExecutorV02asbC0Sch_pSgyF _$ss19UnownedTaskExecutorVyABxhcSchRzlufC _$ss20AsyncFlatMapSequenceV04makeA8IteratorAB0F0Vyxq__GyF _$ss20AsyncFlatMapSequenceV4basexvg @@ -703,6 +756,15 @@ _$ss23AsyncCompactMapSequenceVMa _$ss23AsyncCompactMapSequenceVMn _$ss23AsyncCompactMapSequenceV_9transformAByxq_Gx_q_Sg7ElementQzYactcfC _$ss23AsyncCompactMapSequenceVyxq_GScisMc +_$ss23PlatformExecutorFactoryV04mainB0s04MainB0_pvgZ +_$ss23PlatformExecutorFactoryV04mainB0s04MainB0_pvpZMV +_$ss23PlatformExecutorFactoryV07defaultB0Sch_pvgZ +_$ss23PlatformExecutorFactoryV07defaultB0Sch_pvpZMV +_$ss23PlatformExecutorFactoryVMa +_$ss23PlatformExecutorFactoryVMn +_$ss23PlatformExecutorFactoryVN +_$ss23PlatformExecutorFactoryVs0bC0sMc +_$ss23PlatformExecutorFactoryVs0bC0sWP _$ss23withCheckedContinuation8function_xSS_yScCyxs5NeverOGXEtYalF _$ss23withCheckedContinuation8function_xSS_yScCyxs5NeverOGXEtYalFTu _$ss23withDiscardingTaskGroup9returning4bodyxxm_xs0bcD0VzYaXEtYalF @@ -757,6 +819,51 @@ _$ss24AsyncThrowingMapSequenceVMa _$ss24AsyncThrowingMapSequenceVMn _$ss24AsyncThrowingMapSequenceV_9transformAByxq_Gx_q_7ElementQzYaKctcfC _$ss24AsyncThrowingMapSequenceVyxq_GScisMc +_$ss25UnimplementedMainExecutorC02isbC0Sbvg +_$ss25UnimplementedMainExecutorC02isbC0SbvpMV +_$ss25UnimplementedMainExecutorC13checkIsolatedyyF +_$ss25UnimplementedMainExecutorC3runyyKF +_$ss25UnimplementedMainExecutorC4stopyyF +_$ss25UnimplementedMainExecutorC7enqueueyys0C3JobVnF +_$ss25UnimplementedMainExecutorCABycfC +_$ss25UnimplementedMainExecutorCABycfCTj +_$ss25UnimplementedMainExecutorCABycfCTq +_$ss25UnimplementedMainExecutorCABycfc +_$ss25UnimplementedMainExecutorCMa +_$ss25UnimplementedMainExecutorCMm +_$ss25UnimplementedMainExecutorCMn +_$ss25UnimplementedMainExecutorCMo +_$ss25UnimplementedMainExecutorCMu +_$ss25UnimplementedMainExecutorCN +_$ss25UnimplementedMainExecutorCScFsMc +_$ss25UnimplementedMainExecutorCScFsWP +_$ss25UnimplementedMainExecutorCScfsMc +_$ss25UnimplementedMainExecutorCScfsWP +_$ss25UnimplementedMainExecutorCfD +_$ss25UnimplementedMainExecutorCfd +_$ss25UnimplementedMainExecutorCs07RunLoopC0sMc +_$ss25UnimplementedMainExecutorCs07RunLoopC0sWP +_$ss25UnimplementedMainExecutorCs0bC0sMc +_$ss25UnimplementedMainExecutorCs0bC0sWP +_$ss25UnimplementedTaskExecutorC06isMainC0Sbvg +_$ss25UnimplementedTaskExecutorC06isMainC0SbvpMV +_$ss25UnimplementedTaskExecutorC7enqueueyys0C3JobVnF +_$ss25UnimplementedTaskExecutorCABycfC +_$ss25UnimplementedTaskExecutorCABycfCTj +_$ss25UnimplementedTaskExecutorCABycfCTq +_$ss25UnimplementedTaskExecutorCABycfc +_$ss25UnimplementedTaskExecutorCMa +_$ss25UnimplementedTaskExecutorCMm +_$ss25UnimplementedTaskExecutorCMn +_$ss25UnimplementedTaskExecutorCMo +_$ss25UnimplementedTaskExecutorCMu +_$ss25UnimplementedTaskExecutorCN +_$ss25UnimplementedTaskExecutorCScFsMc +_$ss25UnimplementedTaskExecutorCScFsWP +_$ss25UnimplementedTaskExecutorCSchsMc +_$ss25UnimplementedTaskExecutorCSchsWP +_$ss25UnimplementedTaskExecutorCfD +_$ss25UnimplementedTaskExecutorCfd _$ss27AsyncThrowingFilterSequenceV04makeA8IteratorAB0F0Vyx_GyF _$ss27AsyncThrowingFilterSequenceV10isIncludedySb7ElementQzYaKcvg _$ss27AsyncThrowingFilterSequenceV10isIncludedySb7ElementQzYaKcvpMV @@ -921,10 +1028,16 @@ _$ss5ClockP17minimumResolution8DurationQzvgTj _$ss5ClockP17minimumResolution8DurationQzvgTq _$ss5ClockP3now7InstantQzvgTj _$ss5ClockP3now7InstantQzvgTq +_$ss5ClockP3run_2at9toleranceys11ExecutorJobVn_7InstantQz8DurationQzSgtFTj +_$ss5ClockP3run_2at9toleranceys11ExecutorJobVn_7InstantQz8DurationQzSgtFTq _$ss5ClockP5sleep5until9tolerancey7InstantQz_8DurationQzSgtYaKFTj _$ss5ClockP5sleep5until9tolerancey7InstantQz_8DurationQzSgtYaKFTjTu _$ss5ClockP5sleep5until9tolerancey7InstantQz_8DurationQzSgtYaKFTq _$ss5ClockP7InstantAB_s0B8ProtocolTn +_$ss5ClockP7enqueue_2on2at9toleranceys11ExecutorJobVn_qd__7InstantQz8DurationQzSgtScFRd__lFTj +_$ss5ClockP7enqueue_2on2at9toleranceys11ExecutorJobVn_qd__7InstantQz8DurationQzSgtScFRd__lFTq +_$ss5ClockPsE3run_2at9toleranceys11ExecutorJobVn_7InstantQz8DurationQzSgtF +_$ss5ClockPsE7enqueue_2on2at9toleranceys11ExecutorJobVn_qd__7InstantQz8DurationQzSgtScFRd__lF _$ss5ClockPsE7measurey8DurationQzyyKXEKF _$ss5ClockPsE7measurey8DurationQzyyYaKXEYaKF _$ss5ClockPsE7measurey8DurationQzyyYaKXEYaKFTu @@ -971,6 +1084,7 @@ __swift_concurrency_debug_non_future_adapter __swift_concurrency_debug_supportsPriorityEscalation __swift_concurrency_debug_task_future_wait_resume_adapter __swift_concurrency_debug_task_wait_throwing_resume_adapter +__swift_createJobForTestingOnly _swift_asyncLet_begin _swift_asyncLet_consume _swift_asyncLet_consume_throwing @@ -988,6 +1102,7 @@ _swift_continuation_init _swift_continuation_resume _swift_continuation_throwingResume _swift_continuation_throwingResumeWithError +_swift_createExecutors _swift_defaultActor_deallocate _swift_defaultActor_deallocateResilient _swift_defaultActor_destroy diff --git a/test/abi/Inputs/macOS/arm64/concurrency/baseline-asserts b/test/abi/Inputs/macOS/arm64/concurrency/baseline-asserts index 8833498aa2dc4..9f91995fd1839 100644 --- a/test/abi/Inputs/macOS/arm64/concurrency/baseline-asserts +++ b/test/abi/Inputs/macOS/arm64/concurrency/baseline-asserts @@ -23,6 +23,10 @@ _$sScEMa _$sScEMn _$sScEN _$sScEs5ErrorsMc +_$sScF14isMainExecutorSbvgTj +_$sScF14isMainExecutorSbvgTq +_$sScF20asSchedulingExecutors0bC0_pSgvgTj +_$sScF20asSchedulingExecutors0bC0_pSgvgTq _$sScF7enqueueyyScJFTj _$sScF7enqueueyyScJFTq _$sScF7enqueueyys11ExecutorJobVnFTj @@ -31,8 +35,12 @@ _$sScF7enqueueyys3JobVnFTj _$sScF7enqueueyys3JobVnFTq _$sScFMp _$sScFTL +_$sScFsE14isMainExecutorSbvg +_$sScFsE14isMainExecutorSbvpMV _$sScFsE18_isComplexEqualitySbvg _$sScFsE18_isComplexEqualitySbvpMV +_$sScFsE20asSchedulingExecutors0bC0_pSgvg +_$sScFsE20asSchedulingExecutors0bC0_pSgvpMV _$sScFsE7enqueueyyScJF _$sScFsE7enqueueyys11ExecutorJobVnF _$sScFsE7enqueueyys3JobVnF @@ -92,6 +100,8 @@ _$sScM3run10resultType4bodyxxm_xyYbKScMYcXEtYaKlFZ _$sScM3run10resultType4bodyxxm_xyYbKScMYcXEtYaKlFZTu _$sScM6sharedScMvgZ _$sScM7enqueueyyScJF +_$sScM8executors12MainExecutor_pvgZ +_$sScM8executors12MainExecutor_pvpZMV _$sScMMa _$sScMMm _$sScMMn @@ -205,8 +215,16 @@ _$sScTss5NeverORs_rlE5valuexvgTu _$sScTss5NeverORs_rlE5valuexvpMV _$sScTss5NeverORszABRs_rlE11isCancelledSbvgZ _$sScTss5NeverORszABRs_rlE12basePriorityScPSgvgZ +_$sScTss5NeverORszABRs_rlE15currentExecutorScF_pvgZ +_$sScTss5NeverORszABRs_rlE15currentExecutorScF_pvpZMV _$sScTss5NeverORszABRs_rlE15currentPriorityScPvgZ +_$sScTss5NeverORszABRs_rlE15defaultExecutorSch_pvgZ +_$sScTss5NeverORszABRs_rlE15defaultExecutorSch_pvpZMV _$sScTss5NeverORszABRs_rlE17checkCancellationyyKFZ +_$sScTss5NeverORszABRs_rlE17preferredExecutorSch_pSgvgZ +_$sScTss5NeverORszABRs_rlE17preferredExecutorSch_pSgvpZMV +_$sScTss5NeverORszABRs_rlE25currentSchedulingExecutors0cD0_pSgvgZ +_$sScTss5NeverORszABRs_rlE25currentSchedulingExecutors0cD0_pSgvpZMV _$sScTss5NeverORszABRs_rlE5sleep11nanosecondsys6UInt64V_tYaKFZ _$sScTss5NeverORszABRs_rlE5sleep11nanosecondsys6UInt64V_tYaKFZTu _$sScTss5NeverORszABRs_rlE5sleep5until9tolerance5clocky7InstantQyd___8DurationQyd__Sgqd__tYaKs5ClockRd__lFZ @@ -224,6 +242,7 @@ _$sScc7contextBcvs _$sSccMa _$sSccMn _$sSce15complexEqualityScexh_tcScfRzlufC +_$sSce16asSerialExecutorScf_pSgyF _$sSce18_isComplexEqualitySbvg _$sSce18_isComplexEqualitySbvpMV _$sSce8executorBevM @@ -252,6 +271,8 @@ _$sScfMp _$sScfScFTb _$sScfTL _$sScfsE14assertIsolated_4file4lineySSyXK_s12StaticStringVSutF +_$sScfsE14isMainExecutorSbvg +_$sScfsE14isMainExecutorSbvpMV _$sScfsE20preconditionIsolated_4file4lineySSyXK_s12StaticStringVSutF _$sScfsE23asUnownedSerialExecutorSceyF _$sScfsE31isSameExclusiveExecutionContext5otherSbx_tF @@ -438,6 +459,7 @@ _$ss11JobPriorityV2eeoiySbAB_ABtFZ _$ss11JobPriorityV2geoiySbAB_ABtFZ _$ss11JobPriorityV2leoiySbAB_ABtFZ _$ss11JobPriorityV2neoiySbAB_ABtFZ +_$ss11JobPriorityV8rawValueABs5UInt8V_tcfC _$ss11JobPriorityV8rawValues5UInt8VvM _$ss11JobPriorityV8rawValues5UInt8Vvg _$ss11JobPriorityV8rawValues5UInt8VvpMV @@ -447,6 +469,11 @@ _$ss11JobPriorityVMn _$ss11JobPriorityVN _$ss11JobPriorityVSLsMc _$ss11JobPriorityVSQsMc +_$ss11JobPriorityVyABScPcfC +_$ss12MainExecutorMp +_$ss12MainExecutorPScfTb +_$ss12MainExecutorPs07RunLoopB0Tb +_$ss12MainExecutorTL _$ss13_runAsyncMainyyyyYaKcF _$ss13withTaskGroup2of9returning4bodyq_xm_q_mq_ScGyxGzYaXEtYar0_lF _$ss13withTaskGroup2of9returning4bodyq_xm_q_mq_ScGyxGzYaXEtYar0_lFTu @@ -484,6 +511,22 @@ _$ss15ContinuousClockVMn _$ss15ContinuousClockVN _$ss15ContinuousClockVs0B0sMc _$ss15ContinuousClockVs0B0sWP +_$ss15ExecutorFactoryMp +_$ss15ExecutorFactoryP04mainA0s04MainA0_pvgZTj +_$ss15ExecutorFactoryP04mainA0s04MainA0_pvgZTq +_$ss15ExecutorFactoryP07defaultA0Sch_pvgZTj +_$ss15ExecutorFactoryP07defaultA0Sch_pvgZTq +_$ss15ExecutorFactoryTL +_$ss15RunLoopExecutorMp +_$ss15RunLoopExecutorP3runyyKFTj +_$ss15RunLoopExecutorP3runyyKFTq +_$ss15RunLoopExecutorP4stopyyFTj +_$ss15RunLoopExecutorP4stopyyFTq +_$ss15RunLoopExecutorP8runUntilyySbyXEKFTj +_$ss15RunLoopExecutorP8runUntilyySbyXEKFTq +_$ss15RunLoopExecutorPScFTb +_$ss15RunLoopExecutorPsE8runUntilyySbyXEKF +_$ss15RunLoopExecutorTL _$ss15SuspendingClockV17minimumResolutions8DurationVvg _$ss15SuspendingClockV17minimumResolutions8DurationVvpMV _$ss15SuspendingClockV3nowAB7InstantVvg @@ -544,6 +587,15 @@ _$ss16AsyncMapSequenceVMa _$ss16AsyncMapSequenceVMn _$ss16AsyncMapSequenceV_9transformAByxq_Gx_q_7ElementQzYactcfC _$ss16AsyncMapSequenceVyxq_GScisMc +_$ss18SchedulingExecutorMp +_$ss18SchedulingExecutorP7enqueue_2at9tolerance5clockys0B3JobVn_7InstantQyd__8DurationQyd__Sgqd__ts5ClockRd__lFTj +_$ss18SchedulingExecutorP7enqueue_2at9tolerance5clockys0B3JobVn_7InstantQyd__8DurationQyd__Sgqd__ts5ClockRd__lFTq +_$ss18SchedulingExecutorP7enqueue_5after9tolerance5clockys0B3JobVn_8DurationQyd__AJSgqd__ts5ClockRd__lFTj +_$ss18SchedulingExecutorP7enqueue_5after9tolerance5clockys0B3JobVn_8DurationQyd__AJSgqd__ts5ClockRd__lFTq +_$ss18SchedulingExecutorPScFTb +_$ss18SchedulingExecutorPsE7enqueue_2at9tolerance5clockys0B3JobVn_7InstantQyd__8DurationQyd__Sgqd__ts5ClockRd__lF +_$ss18SchedulingExecutorPsE7enqueue_5after9tolerance5clockys0B3JobVn_8DurationQyd__AJSgqd__ts5ClockRd__lF +_$ss18SchedulingExecutorTL _$ss19AsyncFilterSequenceV04makeA8IteratorAB0E0Vyx_GyF _$ss19AsyncFilterSequenceV10isIncludedySb7ElementQzYacvg _$ss19AsyncFilterSequenceV10isIncludedySb7ElementQzYacvpMV @@ -601,6 +653,7 @@ _$ss19DiscardingTaskGroupV9cancelAllyyF _$ss19DiscardingTaskGroupVMa _$ss19DiscardingTaskGroupVMn _$ss19DiscardingTaskGroupVN +_$ss19UnownedTaskExecutorV02asbC0Sch_pSgyF _$ss19UnownedTaskExecutorVyABxhcSchRzlufC _$ss20AsyncFlatMapSequenceV04makeA8IteratorAB0F0Vyxq__GyF _$ss20AsyncFlatMapSequenceV4basexvg @@ -703,6 +756,15 @@ _$ss23AsyncCompactMapSequenceVMa _$ss23AsyncCompactMapSequenceVMn _$ss23AsyncCompactMapSequenceV_9transformAByxq_Gx_q_Sg7ElementQzYactcfC _$ss23AsyncCompactMapSequenceVyxq_GScisMc +_$ss23PlatformExecutorFactoryV04mainB0s04MainB0_pvgZ +_$ss23PlatformExecutorFactoryV04mainB0s04MainB0_pvpZMV +_$ss23PlatformExecutorFactoryV07defaultB0Sch_pvgZ +_$ss23PlatformExecutorFactoryV07defaultB0Sch_pvpZMV +_$ss23PlatformExecutorFactoryVMa +_$ss23PlatformExecutorFactoryVMn +_$ss23PlatformExecutorFactoryVN +_$ss23PlatformExecutorFactoryVs0bC0sMc +_$ss23PlatformExecutorFactoryVs0bC0sWP _$ss23withCheckedContinuation8function_xSS_yScCyxs5NeverOGXEtYalF _$ss23withCheckedContinuation8function_xSS_yScCyxs5NeverOGXEtYalFTu _$ss23withDiscardingTaskGroup9returning4bodyxxm_xs0bcD0VzYaXEtYalF @@ -757,6 +819,51 @@ _$ss24AsyncThrowingMapSequenceVMa _$ss24AsyncThrowingMapSequenceVMn _$ss24AsyncThrowingMapSequenceV_9transformAByxq_Gx_q_7ElementQzYaKctcfC _$ss24AsyncThrowingMapSequenceVyxq_GScisMc +_$ss25UnimplementedMainExecutorC02isbC0Sbvg +_$ss25UnimplementedMainExecutorC02isbC0SbvpMV +_$ss25UnimplementedMainExecutorC13checkIsolatedyyF +_$ss25UnimplementedMainExecutorC3runyyKF +_$ss25UnimplementedMainExecutorC4stopyyF +_$ss25UnimplementedMainExecutorC7enqueueyys0C3JobVnF +_$ss25UnimplementedMainExecutorCABycfC +_$ss25UnimplementedMainExecutorCABycfCTj +_$ss25UnimplementedMainExecutorCABycfCTq +_$ss25UnimplementedMainExecutorCABycfc +_$ss25UnimplementedMainExecutorCMa +_$ss25UnimplementedMainExecutorCMm +_$ss25UnimplementedMainExecutorCMn +_$ss25UnimplementedMainExecutorCMo +_$ss25UnimplementedMainExecutorCMu +_$ss25UnimplementedMainExecutorCN +_$ss25UnimplementedMainExecutorCScFsMc +_$ss25UnimplementedMainExecutorCScFsWP +_$ss25UnimplementedMainExecutorCScfsMc +_$ss25UnimplementedMainExecutorCScfsWP +_$ss25UnimplementedMainExecutorCfD +_$ss25UnimplementedMainExecutorCfd +_$ss25UnimplementedMainExecutorCs07RunLoopC0sMc +_$ss25UnimplementedMainExecutorCs07RunLoopC0sWP +_$ss25UnimplementedMainExecutorCs0bC0sMc +_$ss25UnimplementedMainExecutorCs0bC0sWP +_$ss25UnimplementedTaskExecutorC06isMainC0Sbvg +_$ss25UnimplementedTaskExecutorC06isMainC0SbvpMV +_$ss25UnimplementedTaskExecutorC7enqueueyys0C3JobVnF +_$ss25UnimplementedTaskExecutorCABycfC +_$ss25UnimplementedTaskExecutorCABycfCTj +_$ss25UnimplementedTaskExecutorCABycfCTq +_$ss25UnimplementedTaskExecutorCABycfc +_$ss25UnimplementedTaskExecutorCMa +_$ss25UnimplementedTaskExecutorCMm +_$ss25UnimplementedTaskExecutorCMn +_$ss25UnimplementedTaskExecutorCMo +_$ss25UnimplementedTaskExecutorCMu +_$ss25UnimplementedTaskExecutorCN +_$ss25UnimplementedTaskExecutorCScFsMc +_$ss25UnimplementedTaskExecutorCScFsWP +_$ss25UnimplementedTaskExecutorCSchsMc +_$ss25UnimplementedTaskExecutorCSchsWP +_$ss25UnimplementedTaskExecutorCfD +_$ss25UnimplementedTaskExecutorCfd _$ss27AsyncThrowingFilterSequenceV04makeA8IteratorAB0F0Vyx_GyF _$ss27AsyncThrowingFilterSequenceV10isIncludedySb7ElementQzYaKcvg _$ss27AsyncThrowingFilterSequenceV10isIncludedySb7ElementQzYaKcvpMV @@ -921,10 +1028,16 @@ _$ss5ClockP17minimumResolution8DurationQzvgTj _$ss5ClockP17minimumResolution8DurationQzvgTq _$ss5ClockP3now7InstantQzvgTj _$ss5ClockP3now7InstantQzvgTq +_$ss5ClockP3run_2at9toleranceys11ExecutorJobVn_7InstantQz8DurationQzSgtFTj +_$ss5ClockP3run_2at9toleranceys11ExecutorJobVn_7InstantQz8DurationQzSgtFTq _$ss5ClockP5sleep5until9tolerancey7InstantQz_8DurationQzSgtYaKFTj _$ss5ClockP5sleep5until9tolerancey7InstantQz_8DurationQzSgtYaKFTjTu _$ss5ClockP5sleep5until9tolerancey7InstantQz_8DurationQzSgtYaKFTq _$ss5ClockP7InstantAB_s0B8ProtocolTn +_$ss5ClockP7enqueue_2on2at9toleranceys11ExecutorJobVn_qd__7InstantQz8DurationQzSgtScFRd__lFTj +_$ss5ClockP7enqueue_2on2at9toleranceys11ExecutorJobVn_qd__7InstantQz8DurationQzSgtScFRd__lFTq +_$ss5ClockPsE3run_2at9toleranceys11ExecutorJobVn_7InstantQz8DurationQzSgtF +_$ss5ClockPsE7enqueue_2on2at9toleranceys11ExecutorJobVn_qd__7InstantQz8DurationQzSgtScFRd__lF _$ss5ClockPsE7measurey8DurationQzyyKXEKF _$ss5ClockPsE7measurey8DurationQzyyYaKXEYaKF _$ss5ClockPsE7measurey8DurationQzyyYaKXEYaKFTu @@ -971,6 +1084,7 @@ __swift_concurrency_debug_non_future_adapter __swift_concurrency_debug_supportsPriorityEscalation __swift_concurrency_debug_task_future_wait_resume_adapter __swift_concurrency_debug_task_wait_throwing_resume_adapter +__swift_createJobForTestingOnly _swift_asyncLet_begin _swift_asyncLet_consume _swift_asyncLet_consume_throwing @@ -988,6 +1102,7 @@ _swift_continuation_init _swift_continuation_resume _swift_continuation_throwingResume _swift_continuation_throwingResumeWithError +_swift_createExecutors _swift_defaultActor_deallocate _swift_defaultActor_deallocateResilient _swift_defaultActor_destroy diff --git a/test/abi/Inputs/macOS/x86_64/concurrency/baseline b/test/abi/Inputs/macOS/x86_64/concurrency/baseline index 8833498aa2dc4..9f91995fd1839 100644 --- a/test/abi/Inputs/macOS/x86_64/concurrency/baseline +++ b/test/abi/Inputs/macOS/x86_64/concurrency/baseline @@ -23,6 +23,10 @@ _$sScEMa _$sScEMn _$sScEN _$sScEs5ErrorsMc +_$sScF14isMainExecutorSbvgTj +_$sScF14isMainExecutorSbvgTq +_$sScF20asSchedulingExecutors0bC0_pSgvgTj +_$sScF20asSchedulingExecutors0bC0_pSgvgTq _$sScF7enqueueyyScJFTj _$sScF7enqueueyyScJFTq _$sScF7enqueueyys11ExecutorJobVnFTj @@ -31,8 +35,12 @@ _$sScF7enqueueyys3JobVnFTj _$sScF7enqueueyys3JobVnFTq _$sScFMp _$sScFTL +_$sScFsE14isMainExecutorSbvg +_$sScFsE14isMainExecutorSbvpMV _$sScFsE18_isComplexEqualitySbvg _$sScFsE18_isComplexEqualitySbvpMV +_$sScFsE20asSchedulingExecutors0bC0_pSgvg +_$sScFsE20asSchedulingExecutors0bC0_pSgvpMV _$sScFsE7enqueueyyScJF _$sScFsE7enqueueyys11ExecutorJobVnF _$sScFsE7enqueueyys3JobVnF @@ -92,6 +100,8 @@ _$sScM3run10resultType4bodyxxm_xyYbKScMYcXEtYaKlFZ _$sScM3run10resultType4bodyxxm_xyYbKScMYcXEtYaKlFZTu _$sScM6sharedScMvgZ _$sScM7enqueueyyScJF +_$sScM8executors12MainExecutor_pvgZ +_$sScM8executors12MainExecutor_pvpZMV _$sScMMa _$sScMMm _$sScMMn @@ -205,8 +215,16 @@ _$sScTss5NeverORs_rlE5valuexvgTu _$sScTss5NeverORs_rlE5valuexvpMV _$sScTss5NeverORszABRs_rlE11isCancelledSbvgZ _$sScTss5NeverORszABRs_rlE12basePriorityScPSgvgZ +_$sScTss5NeverORszABRs_rlE15currentExecutorScF_pvgZ +_$sScTss5NeverORszABRs_rlE15currentExecutorScF_pvpZMV _$sScTss5NeverORszABRs_rlE15currentPriorityScPvgZ +_$sScTss5NeverORszABRs_rlE15defaultExecutorSch_pvgZ +_$sScTss5NeverORszABRs_rlE15defaultExecutorSch_pvpZMV _$sScTss5NeverORszABRs_rlE17checkCancellationyyKFZ +_$sScTss5NeverORszABRs_rlE17preferredExecutorSch_pSgvgZ +_$sScTss5NeverORszABRs_rlE17preferredExecutorSch_pSgvpZMV +_$sScTss5NeverORszABRs_rlE25currentSchedulingExecutors0cD0_pSgvgZ +_$sScTss5NeverORszABRs_rlE25currentSchedulingExecutors0cD0_pSgvpZMV _$sScTss5NeverORszABRs_rlE5sleep11nanosecondsys6UInt64V_tYaKFZ _$sScTss5NeverORszABRs_rlE5sleep11nanosecondsys6UInt64V_tYaKFZTu _$sScTss5NeverORszABRs_rlE5sleep5until9tolerance5clocky7InstantQyd___8DurationQyd__Sgqd__tYaKs5ClockRd__lFZ @@ -224,6 +242,7 @@ _$sScc7contextBcvs _$sSccMa _$sSccMn _$sSce15complexEqualityScexh_tcScfRzlufC +_$sSce16asSerialExecutorScf_pSgyF _$sSce18_isComplexEqualitySbvg _$sSce18_isComplexEqualitySbvpMV _$sSce8executorBevM @@ -252,6 +271,8 @@ _$sScfMp _$sScfScFTb _$sScfTL _$sScfsE14assertIsolated_4file4lineySSyXK_s12StaticStringVSutF +_$sScfsE14isMainExecutorSbvg +_$sScfsE14isMainExecutorSbvpMV _$sScfsE20preconditionIsolated_4file4lineySSyXK_s12StaticStringVSutF _$sScfsE23asUnownedSerialExecutorSceyF _$sScfsE31isSameExclusiveExecutionContext5otherSbx_tF @@ -438,6 +459,7 @@ _$ss11JobPriorityV2eeoiySbAB_ABtFZ _$ss11JobPriorityV2geoiySbAB_ABtFZ _$ss11JobPriorityV2leoiySbAB_ABtFZ _$ss11JobPriorityV2neoiySbAB_ABtFZ +_$ss11JobPriorityV8rawValueABs5UInt8V_tcfC _$ss11JobPriorityV8rawValues5UInt8VvM _$ss11JobPriorityV8rawValues5UInt8Vvg _$ss11JobPriorityV8rawValues5UInt8VvpMV @@ -447,6 +469,11 @@ _$ss11JobPriorityVMn _$ss11JobPriorityVN _$ss11JobPriorityVSLsMc _$ss11JobPriorityVSQsMc +_$ss11JobPriorityVyABScPcfC +_$ss12MainExecutorMp +_$ss12MainExecutorPScfTb +_$ss12MainExecutorPs07RunLoopB0Tb +_$ss12MainExecutorTL _$ss13_runAsyncMainyyyyYaKcF _$ss13withTaskGroup2of9returning4bodyq_xm_q_mq_ScGyxGzYaXEtYar0_lF _$ss13withTaskGroup2of9returning4bodyq_xm_q_mq_ScGyxGzYaXEtYar0_lFTu @@ -484,6 +511,22 @@ _$ss15ContinuousClockVMn _$ss15ContinuousClockVN _$ss15ContinuousClockVs0B0sMc _$ss15ContinuousClockVs0B0sWP +_$ss15ExecutorFactoryMp +_$ss15ExecutorFactoryP04mainA0s04MainA0_pvgZTj +_$ss15ExecutorFactoryP04mainA0s04MainA0_pvgZTq +_$ss15ExecutorFactoryP07defaultA0Sch_pvgZTj +_$ss15ExecutorFactoryP07defaultA0Sch_pvgZTq +_$ss15ExecutorFactoryTL +_$ss15RunLoopExecutorMp +_$ss15RunLoopExecutorP3runyyKFTj +_$ss15RunLoopExecutorP3runyyKFTq +_$ss15RunLoopExecutorP4stopyyFTj +_$ss15RunLoopExecutorP4stopyyFTq +_$ss15RunLoopExecutorP8runUntilyySbyXEKFTj +_$ss15RunLoopExecutorP8runUntilyySbyXEKFTq +_$ss15RunLoopExecutorPScFTb +_$ss15RunLoopExecutorPsE8runUntilyySbyXEKF +_$ss15RunLoopExecutorTL _$ss15SuspendingClockV17minimumResolutions8DurationVvg _$ss15SuspendingClockV17minimumResolutions8DurationVvpMV _$ss15SuspendingClockV3nowAB7InstantVvg @@ -544,6 +587,15 @@ _$ss16AsyncMapSequenceVMa _$ss16AsyncMapSequenceVMn _$ss16AsyncMapSequenceV_9transformAByxq_Gx_q_7ElementQzYactcfC _$ss16AsyncMapSequenceVyxq_GScisMc +_$ss18SchedulingExecutorMp +_$ss18SchedulingExecutorP7enqueue_2at9tolerance5clockys0B3JobVn_7InstantQyd__8DurationQyd__Sgqd__ts5ClockRd__lFTj +_$ss18SchedulingExecutorP7enqueue_2at9tolerance5clockys0B3JobVn_7InstantQyd__8DurationQyd__Sgqd__ts5ClockRd__lFTq +_$ss18SchedulingExecutorP7enqueue_5after9tolerance5clockys0B3JobVn_8DurationQyd__AJSgqd__ts5ClockRd__lFTj +_$ss18SchedulingExecutorP7enqueue_5after9tolerance5clockys0B3JobVn_8DurationQyd__AJSgqd__ts5ClockRd__lFTq +_$ss18SchedulingExecutorPScFTb +_$ss18SchedulingExecutorPsE7enqueue_2at9tolerance5clockys0B3JobVn_7InstantQyd__8DurationQyd__Sgqd__ts5ClockRd__lF +_$ss18SchedulingExecutorPsE7enqueue_5after9tolerance5clockys0B3JobVn_8DurationQyd__AJSgqd__ts5ClockRd__lF +_$ss18SchedulingExecutorTL _$ss19AsyncFilterSequenceV04makeA8IteratorAB0E0Vyx_GyF _$ss19AsyncFilterSequenceV10isIncludedySb7ElementQzYacvg _$ss19AsyncFilterSequenceV10isIncludedySb7ElementQzYacvpMV @@ -601,6 +653,7 @@ _$ss19DiscardingTaskGroupV9cancelAllyyF _$ss19DiscardingTaskGroupVMa _$ss19DiscardingTaskGroupVMn _$ss19DiscardingTaskGroupVN +_$ss19UnownedTaskExecutorV02asbC0Sch_pSgyF _$ss19UnownedTaskExecutorVyABxhcSchRzlufC _$ss20AsyncFlatMapSequenceV04makeA8IteratorAB0F0Vyxq__GyF _$ss20AsyncFlatMapSequenceV4basexvg @@ -703,6 +756,15 @@ _$ss23AsyncCompactMapSequenceVMa _$ss23AsyncCompactMapSequenceVMn _$ss23AsyncCompactMapSequenceV_9transformAByxq_Gx_q_Sg7ElementQzYactcfC _$ss23AsyncCompactMapSequenceVyxq_GScisMc +_$ss23PlatformExecutorFactoryV04mainB0s04MainB0_pvgZ +_$ss23PlatformExecutorFactoryV04mainB0s04MainB0_pvpZMV +_$ss23PlatformExecutorFactoryV07defaultB0Sch_pvgZ +_$ss23PlatformExecutorFactoryV07defaultB0Sch_pvpZMV +_$ss23PlatformExecutorFactoryVMa +_$ss23PlatformExecutorFactoryVMn +_$ss23PlatformExecutorFactoryVN +_$ss23PlatformExecutorFactoryVs0bC0sMc +_$ss23PlatformExecutorFactoryVs0bC0sWP _$ss23withCheckedContinuation8function_xSS_yScCyxs5NeverOGXEtYalF _$ss23withCheckedContinuation8function_xSS_yScCyxs5NeverOGXEtYalFTu _$ss23withDiscardingTaskGroup9returning4bodyxxm_xs0bcD0VzYaXEtYalF @@ -757,6 +819,51 @@ _$ss24AsyncThrowingMapSequenceVMa _$ss24AsyncThrowingMapSequenceVMn _$ss24AsyncThrowingMapSequenceV_9transformAByxq_Gx_q_7ElementQzYaKctcfC _$ss24AsyncThrowingMapSequenceVyxq_GScisMc +_$ss25UnimplementedMainExecutorC02isbC0Sbvg +_$ss25UnimplementedMainExecutorC02isbC0SbvpMV +_$ss25UnimplementedMainExecutorC13checkIsolatedyyF +_$ss25UnimplementedMainExecutorC3runyyKF +_$ss25UnimplementedMainExecutorC4stopyyF +_$ss25UnimplementedMainExecutorC7enqueueyys0C3JobVnF +_$ss25UnimplementedMainExecutorCABycfC +_$ss25UnimplementedMainExecutorCABycfCTj +_$ss25UnimplementedMainExecutorCABycfCTq +_$ss25UnimplementedMainExecutorCABycfc +_$ss25UnimplementedMainExecutorCMa +_$ss25UnimplementedMainExecutorCMm +_$ss25UnimplementedMainExecutorCMn +_$ss25UnimplementedMainExecutorCMo +_$ss25UnimplementedMainExecutorCMu +_$ss25UnimplementedMainExecutorCN +_$ss25UnimplementedMainExecutorCScFsMc +_$ss25UnimplementedMainExecutorCScFsWP +_$ss25UnimplementedMainExecutorCScfsMc +_$ss25UnimplementedMainExecutorCScfsWP +_$ss25UnimplementedMainExecutorCfD +_$ss25UnimplementedMainExecutorCfd +_$ss25UnimplementedMainExecutorCs07RunLoopC0sMc +_$ss25UnimplementedMainExecutorCs07RunLoopC0sWP +_$ss25UnimplementedMainExecutorCs0bC0sMc +_$ss25UnimplementedMainExecutorCs0bC0sWP +_$ss25UnimplementedTaskExecutorC06isMainC0Sbvg +_$ss25UnimplementedTaskExecutorC06isMainC0SbvpMV +_$ss25UnimplementedTaskExecutorC7enqueueyys0C3JobVnF +_$ss25UnimplementedTaskExecutorCABycfC +_$ss25UnimplementedTaskExecutorCABycfCTj +_$ss25UnimplementedTaskExecutorCABycfCTq +_$ss25UnimplementedTaskExecutorCABycfc +_$ss25UnimplementedTaskExecutorCMa +_$ss25UnimplementedTaskExecutorCMm +_$ss25UnimplementedTaskExecutorCMn +_$ss25UnimplementedTaskExecutorCMo +_$ss25UnimplementedTaskExecutorCMu +_$ss25UnimplementedTaskExecutorCN +_$ss25UnimplementedTaskExecutorCScFsMc +_$ss25UnimplementedTaskExecutorCScFsWP +_$ss25UnimplementedTaskExecutorCSchsMc +_$ss25UnimplementedTaskExecutorCSchsWP +_$ss25UnimplementedTaskExecutorCfD +_$ss25UnimplementedTaskExecutorCfd _$ss27AsyncThrowingFilterSequenceV04makeA8IteratorAB0F0Vyx_GyF _$ss27AsyncThrowingFilterSequenceV10isIncludedySb7ElementQzYaKcvg _$ss27AsyncThrowingFilterSequenceV10isIncludedySb7ElementQzYaKcvpMV @@ -921,10 +1028,16 @@ _$ss5ClockP17minimumResolution8DurationQzvgTj _$ss5ClockP17minimumResolution8DurationQzvgTq _$ss5ClockP3now7InstantQzvgTj _$ss5ClockP3now7InstantQzvgTq +_$ss5ClockP3run_2at9toleranceys11ExecutorJobVn_7InstantQz8DurationQzSgtFTj +_$ss5ClockP3run_2at9toleranceys11ExecutorJobVn_7InstantQz8DurationQzSgtFTq _$ss5ClockP5sleep5until9tolerancey7InstantQz_8DurationQzSgtYaKFTj _$ss5ClockP5sleep5until9tolerancey7InstantQz_8DurationQzSgtYaKFTjTu _$ss5ClockP5sleep5until9tolerancey7InstantQz_8DurationQzSgtYaKFTq _$ss5ClockP7InstantAB_s0B8ProtocolTn +_$ss5ClockP7enqueue_2on2at9toleranceys11ExecutorJobVn_qd__7InstantQz8DurationQzSgtScFRd__lFTj +_$ss5ClockP7enqueue_2on2at9toleranceys11ExecutorJobVn_qd__7InstantQz8DurationQzSgtScFRd__lFTq +_$ss5ClockPsE3run_2at9toleranceys11ExecutorJobVn_7InstantQz8DurationQzSgtF +_$ss5ClockPsE7enqueue_2on2at9toleranceys11ExecutorJobVn_qd__7InstantQz8DurationQzSgtScFRd__lF _$ss5ClockPsE7measurey8DurationQzyyKXEKF _$ss5ClockPsE7measurey8DurationQzyyYaKXEYaKF _$ss5ClockPsE7measurey8DurationQzyyYaKXEYaKFTu @@ -971,6 +1084,7 @@ __swift_concurrency_debug_non_future_adapter __swift_concurrency_debug_supportsPriorityEscalation __swift_concurrency_debug_task_future_wait_resume_adapter __swift_concurrency_debug_task_wait_throwing_resume_adapter +__swift_createJobForTestingOnly _swift_asyncLet_begin _swift_asyncLet_consume _swift_asyncLet_consume_throwing @@ -988,6 +1102,7 @@ _swift_continuation_init _swift_continuation_resume _swift_continuation_throwingResume _swift_continuation_throwingResumeWithError +_swift_createExecutors _swift_defaultActor_deallocate _swift_defaultActor_deallocateResilient _swift_defaultActor_destroy diff --git a/test/abi/Inputs/macOS/x86_64/concurrency/baseline-asserts b/test/abi/Inputs/macOS/x86_64/concurrency/baseline-asserts index 8833498aa2dc4..9f91995fd1839 100644 --- a/test/abi/Inputs/macOS/x86_64/concurrency/baseline-asserts +++ b/test/abi/Inputs/macOS/x86_64/concurrency/baseline-asserts @@ -23,6 +23,10 @@ _$sScEMa _$sScEMn _$sScEN _$sScEs5ErrorsMc +_$sScF14isMainExecutorSbvgTj +_$sScF14isMainExecutorSbvgTq +_$sScF20asSchedulingExecutors0bC0_pSgvgTj +_$sScF20asSchedulingExecutors0bC0_pSgvgTq _$sScF7enqueueyyScJFTj _$sScF7enqueueyyScJFTq _$sScF7enqueueyys11ExecutorJobVnFTj @@ -31,8 +35,12 @@ _$sScF7enqueueyys3JobVnFTj _$sScF7enqueueyys3JobVnFTq _$sScFMp _$sScFTL +_$sScFsE14isMainExecutorSbvg +_$sScFsE14isMainExecutorSbvpMV _$sScFsE18_isComplexEqualitySbvg _$sScFsE18_isComplexEqualitySbvpMV +_$sScFsE20asSchedulingExecutors0bC0_pSgvg +_$sScFsE20asSchedulingExecutors0bC0_pSgvpMV _$sScFsE7enqueueyyScJF _$sScFsE7enqueueyys11ExecutorJobVnF _$sScFsE7enqueueyys3JobVnF @@ -92,6 +100,8 @@ _$sScM3run10resultType4bodyxxm_xyYbKScMYcXEtYaKlFZ _$sScM3run10resultType4bodyxxm_xyYbKScMYcXEtYaKlFZTu _$sScM6sharedScMvgZ _$sScM7enqueueyyScJF +_$sScM8executors12MainExecutor_pvgZ +_$sScM8executors12MainExecutor_pvpZMV _$sScMMa _$sScMMm _$sScMMn @@ -205,8 +215,16 @@ _$sScTss5NeverORs_rlE5valuexvgTu _$sScTss5NeverORs_rlE5valuexvpMV _$sScTss5NeverORszABRs_rlE11isCancelledSbvgZ _$sScTss5NeverORszABRs_rlE12basePriorityScPSgvgZ +_$sScTss5NeverORszABRs_rlE15currentExecutorScF_pvgZ +_$sScTss5NeverORszABRs_rlE15currentExecutorScF_pvpZMV _$sScTss5NeverORszABRs_rlE15currentPriorityScPvgZ +_$sScTss5NeverORszABRs_rlE15defaultExecutorSch_pvgZ +_$sScTss5NeverORszABRs_rlE15defaultExecutorSch_pvpZMV _$sScTss5NeverORszABRs_rlE17checkCancellationyyKFZ +_$sScTss5NeverORszABRs_rlE17preferredExecutorSch_pSgvgZ +_$sScTss5NeverORszABRs_rlE17preferredExecutorSch_pSgvpZMV +_$sScTss5NeverORszABRs_rlE25currentSchedulingExecutors0cD0_pSgvgZ +_$sScTss5NeverORszABRs_rlE25currentSchedulingExecutors0cD0_pSgvpZMV _$sScTss5NeverORszABRs_rlE5sleep11nanosecondsys6UInt64V_tYaKFZ _$sScTss5NeverORszABRs_rlE5sleep11nanosecondsys6UInt64V_tYaKFZTu _$sScTss5NeverORszABRs_rlE5sleep5until9tolerance5clocky7InstantQyd___8DurationQyd__Sgqd__tYaKs5ClockRd__lFZ @@ -224,6 +242,7 @@ _$sScc7contextBcvs _$sSccMa _$sSccMn _$sSce15complexEqualityScexh_tcScfRzlufC +_$sSce16asSerialExecutorScf_pSgyF _$sSce18_isComplexEqualitySbvg _$sSce18_isComplexEqualitySbvpMV _$sSce8executorBevM @@ -252,6 +271,8 @@ _$sScfMp _$sScfScFTb _$sScfTL _$sScfsE14assertIsolated_4file4lineySSyXK_s12StaticStringVSutF +_$sScfsE14isMainExecutorSbvg +_$sScfsE14isMainExecutorSbvpMV _$sScfsE20preconditionIsolated_4file4lineySSyXK_s12StaticStringVSutF _$sScfsE23asUnownedSerialExecutorSceyF _$sScfsE31isSameExclusiveExecutionContext5otherSbx_tF @@ -438,6 +459,7 @@ _$ss11JobPriorityV2eeoiySbAB_ABtFZ _$ss11JobPriorityV2geoiySbAB_ABtFZ _$ss11JobPriorityV2leoiySbAB_ABtFZ _$ss11JobPriorityV2neoiySbAB_ABtFZ +_$ss11JobPriorityV8rawValueABs5UInt8V_tcfC _$ss11JobPriorityV8rawValues5UInt8VvM _$ss11JobPriorityV8rawValues5UInt8Vvg _$ss11JobPriorityV8rawValues5UInt8VvpMV @@ -447,6 +469,11 @@ _$ss11JobPriorityVMn _$ss11JobPriorityVN _$ss11JobPriorityVSLsMc _$ss11JobPriorityVSQsMc +_$ss11JobPriorityVyABScPcfC +_$ss12MainExecutorMp +_$ss12MainExecutorPScfTb +_$ss12MainExecutorPs07RunLoopB0Tb +_$ss12MainExecutorTL _$ss13_runAsyncMainyyyyYaKcF _$ss13withTaskGroup2of9returning4bodyq_xm_q_mq_ScGyxGzYaXEtYar0_lF _$ss13withTaskGroup2of9returning4bodyq_xm_q_mq_ScGyxGzYaXEtYar0_lFTu @@ -484,6 +511,22 @@ _$ss15ContinuousClockVMn _$ss15ContinuousClockVN _$ss15ContinuousClockVs0B0sMc _$ss15ContinuousClockVs0B0sWP +_$ss15ExecutorFactoryMp +_$ss15ExecutorFactoryP04mainA0s04MainA0_pvgZTj +_$ss15ExecutorFactoryP04mainA0s04MainA0_pvgZTq +_$ss15ExecutorFactoryP07defaultA0Sch_pvgZTj +_$ss15ExecutorFactoryP07defaultA0Sch_pvgZTq +_$ss15ExecutorFactoryTL +_$ss15RunLoopExecutorMp +_$ss15RunLoopExecutorP3runyyKFTj +_$ss15RunLoopExecutorP3runyyKFTq +_$ss15RunLoopExecutorP4stopyyFTj +_$ss15RunLoopExecutorP4stopyyFTq +_$ss15RunLoopExecutorP8runUntilyySbyXEKFTj +_$ss15RunLoopExecutorP8runUntilyySbyXEKFTq +_$ss15RunLoopExecutorPScFTb +_$ss15RunLoopExecutorPsE8runUntilyySbyXEKF +_$ss15RunLoopExecutorTL _$ss15SuspendingClockV17minimumResolutions8DurationVvg _$ss15SuspendingClockV17minimumResolutions8DurationVvpMV _$ss15SuspendingClockV3nowAB7InstantVvg @@ -544,6 +587,15 @@ _$ss16AsyncMapSequenceVMa _$ss16AsyncMapSequenceVMn _$ss16AsyncMapSequenceV_9transformAByxq_Gx_q_7ElementQzYactcfC _$ss16AsyncMapSequenceVyxq_GScisMc +_$ss18SchedulingExecutorMp +_$ss18SchedulingExecutorP7enqueue_2at9tolerance5clockys0B3JobVn_7InstantQyd__8DurationQyd__Sgqd__ts5ClockRd__lFTj +_$ss18SchedulingExecutorP7enqueue_2at9tolerance5clockys0B3JobVn_7InstantQyd__8DurationQyd__Sgqd__ts5ClockRd__lFTq +_$ss18SchedulingExecutorP7enqueue_5after9tolerance5clockys0B3JobVn_8DurationQyd__AJSgqd__ts5ClockRd__lFTj +_$ss18SchedulingExecutorP7enqueue_5after9tolerance5clockys0B3JobVn_8DurationQyd__AJSgqd__ts5ClockRd__lFTq +_$ss18SchedulingExecutorPScFTb +_$ss18SchedulingExecutorPsE7enqueue_2at9tolerance5clockys0B3JobVn_7InstantQyd__8DurationQyd__Sgqd__ts5ClockRd__lF +_$ss18SchedulingExecutorPsE7enqueue_5after9tolerance5clockys0B3JobVn_8DurationQyd__AJSgqd__ts5ClockRd__lF +_$ss18SchedulingExecutorTL _$ss19AsyncFilterSequenceV04makeA8IteratorAB0E0Vyx_GyF _$ss19AsyncFilterSequenceV10isIncludedySb7ElementQzYacvg _$ss19AsyncFilterSequenceV10isIncludedySb7ElementQzYacvpMV @@ -601,6 +653,7 @@ _$ss19DiscardingTaskGroupV9cancelAllyyF _$ss19DiscardingTaskGroupVMa _$ss19DiscardingTaskGroupVMn _$ss19DiscardingTaskGroupVN +_$ss19UnownedTaskExecutorV02asbC0Sch_pSgyF _$ss19UnownedTaskExecutorVyABxhcSchRzlufC _$ss20AsyncFlatMapSequenceV04makeA8IteratorAB0F0Vyxq__GyF _$ss20AsyncFlatMapSequenceV4basexvg @@ -703,6 +756,15 @@ _$ss23AsyncCompactMapSequenceVMa _$ss23AsyncCompactMapSequenceVMn _$ss23AsyncCompactMapSequenceV_9transformAByxq_Gx_q_Sg7ElementQzYactcfC _$ss23AsyncCompactMapSequenceVyxq_GScisMc +_$ss23PlatformExecutorFactoryV04mainB0s04MainB0_pvgZ +_$ss23PlatformExecutorFactoryV04mainB0s04MainB0_pvpZMV +_$ss23PlatformExecutorFactoryV07defaultB0Sch_pvgZ +_$ss23PlatformExecutorFactoryV07defaultB0Sch_pvpZMV +_$ss23PlatformExecutorFactoryVMa +_$ss23PlatformExecutorFactoryVMn +_$ss23PlatformExecutorFactoryVN +_$ss23PlatformExecutorFactoryVs0bC0sMc +_$ss23PlatformExecutorFactoryVs0bC0sWP _$ss23withCheckedContinuation8function_xSS_yScCyxs5NeverOGXEtYalF _$ss23withCheckedContinuation8function_xSS_yScCyxs5NeverOGXEtYalFTu _$ss23withDiscardingTaskGroup9returning4bodyxxm_xs0bcD0VzYaXEtYalF @@ -757,6 +819,51 @@ _$ss24AsyncThrowingMapSequenceVMa _$ss24AsyncThrowingMapSequenceVMn _$ss24AsyncThrowingMapSequenceV_9transformAByxq_Gx_q_7ElementQzYaKctcfC _$ss24AsyncThrowingMapSequenceVyxq_GScisMc +_$ss25UnimplementedMainExecutorC02isbC0Sbvg +_$ss25UnimplementedMainExecutorC02isbC0SbvpMV +_$ss25UnimplementedMainExecutorC13checkIsolatedyyF +_$ss25UnimplementedMainExecutorC3runyyKF +_$ss25UnimplementedMainExecutorC4stopyyF +_$ss25UnimplementedMainExecutorC7enqueueyys0C3JobVnF +_$ss25UnimplementedMainExecutorCABycfC +_$ss25UnimplementedMainExecutorCABycfCTj +_$ss25UnimplementedMainExecutorCABycfCTq +_$ss25UnimplementedMainExecutorCABycfc +_$ss25UnimplementedMainExecutorCMa +_$ss25UnimplementedMainExecutorCMm +_$ss25UnimplementedMainExecutorCMn +_$ss25UnimplementedMainExecutorCMo +_$ss25UnimplementedMainExecutorCMu +_$ss25UnimplementedMainExecutorCN +_$ss25UnimplementedMainExecutorCScFsMc +_$ss25UnimplementedMainExecutorCScFsWP +_$ss25UnimplementedMainExecutorCScfsMc +_$ss25UnimplementedMainExecutorCScfsWP +_$ss25UnimplementedMainExecutorCfD +_$ss25UnimplementedMainExecutorCfd +_$ss25UnimplementedMainExecutorCs07RunLoopC0sMc +_$ss25UnimplementedMainExecutorCs07RunLoopC0sWP +_$ss25UnimplementedMainExecutorCs0bC0sMc +_$ss25UnimplementedMainExecutorCs0bC0sWP +_$ss25UnimplementedTaskExecutorC06isMainC0Sbvg +_$ss25UnimplementedTaskExecutorC06isMainC0SbvpMV +_$ss25UnimplementedTaskExecutorC7enqueueyys0C3JobVnF +_$ss25UnimplementedTaskExecutorCABycfC +_$ss25UnimplementedTaskExecutorCABycfCTj +_$ss25UnimplementedTaskExecutorCABycfCTq +_$ss25UnimplementedTaskExecutorCABycfc +_$ss25UnimplementedTaskExecutorCMa +_$ss25UnimplementedTaskExecutorCMm +_$ss25UnimplementedTaskExecutorCMn +_$ss25UnimplementedTaskExecutorCMo +_$ss25UnimplementedTaskExecutorCMu +_$ss25UnimplementedTaskExecutorCN +_$ss25UnimplementedTaskExecutorCScFsMc +_$ss25UnimplementedTaskExecutorCScFsWP +_$ss25UnimplementedTaskExecutorCSchsMc +_$ss25UnimplementedTaskExecutorCSchsWP +_$ss25UnimplementedTaskExecutorCfD +_$ss25UnimplementedTaskExecutorCfd _$ss27AsyncThrowingFilterSequenceV04makeA8IteratorAB0F0Vyx_GyF _$ss27AsyncThrowingFilterSequenceV10isIncludedySb7ElementQzYaKcvg _$ss27AsyncThrowingFilterSequenceV10isIncludedySb7ElementQzYaKcvpMV @@ -921,10 +1028,16 @@ _$ss5ClockP17minimumResolution8DurationQzvgTj _$ss5ClockP17minimumResolution8DurationQzvgTq _$ss5ClockP3now7InstantQzvgTj _$ss5ClockP3now7InstantQzvgTq +_$ss5ClockP3run_2at9toleranceys11ExecutorJobVn_7InstantQz8DurationQzSgtFTj +_$ss5ClockP3run_2at9toleranceys11ExecutorJobVn_7InstantQz8DurationQzSgtFTq _$ss5ClockP5sleep5until9tolerancey7InstantQz_8DurationQzSgtYaKFTj _$ss5ClockP5sleep5until9tolerancey7InstantQz_8DurationQzSgtYaKFTjTu _$ss5ClockP5sleep5until9tolerancey7InstantQz_8DurationQzSgtYaKFTq _$ss5ClockP7InstantAB_s0B8ProtocolTn +_$ss5ClockP7enqueue_2on2at9toleranceys11ExecutorJobVn_qd__7InstantQz8DurationQzSgtScFRd__lFTj +_$ss5ClockP7enqueue_2on2at9toleranceys11ExecutorJobVn_qd__7InstantQz8DurationQzSgtScFRd__lFTq +_$ss5ClockPsE3run_2at9toleranceys11ExecutorJobVn_7InstantQz8DurationQzSgtF +_$ss5ClockPsE7enqueue_2on2at9toleranceys11ExecutorJobVn_qd__7InstantQz8DurationQzSgtScFRd__lF _$ss5ClockPsE7measurey8DurationQzyyKXEKF _$ss5ClockPsE7measurey8DurationQzyyYaKXEYaKF _$ss5ClockPsE7measurey8DurationQzyyYaKXEYaKFTu @@ -971,6 +1084,7 @@ __swift_concurrency_debug_non_future_adapter __swift_concurrency_debug_supportsPriorityEscalation __swift_concurrency_debug_task_future_wait_resume_adapter __swift_concurrency_debug_task_wait_throwing_resume_adapter +__swift_createJobForTestingOnly _swift_asyncLet_begin _swift_asyncLet_consume _swift_asyncLet_consume_throwing @@ -988,6 +1102,7 @@ _swift_continuation_init _swift_continuation_resume _swift_continuation_throwingResume _swift_continuation_throwingResumeWithError +_swift_createExecutors _swift_defaultActor_deallocate _swift_defaultActor_deallocateResilient _swift_defaultActor_destroy From b0671c9d380980bdb8525e8367104837c235dbee Mon Sep 17 00:00:00 2001 From: Eric Miotto Date: Fri, 29 Aug 2025 14:56:30 -0700 Subject: [PATCH 3/5] [Concurrency] Add availability to one of the ExecutorJob extensions Without this, we may fail building Concurrency when enforcing strict availability. Addresses rdar://159473855 --- stdlib/public/Concurrency/PartialAsyncTask.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/stdlib/public/Concurrency/PartialAsyncTask.swift b/stdlib/public/Concurrency/PartialAsyncTask.swift index 7871e106df0f9..a255d34d3454a 100644 --- a/stdlib/public/Concurrency/PartialAsyncTask.swift +++ b/stdlib/public/Concurrency/PartialAsyncTask.swift @@ -454,6 +454,7 @@ extension ExecutorJob { // Helper to create a trampoline job to execute a job on a specified // executor. +@available(StdlibDeploymentTarget 6.2, *) extension ExecutorJob { /// Create a trampoline to enqueue the specified job on the specified From 089b61da9235614159ad30a750b744d727f73803 Mon Sep 17 00:00:00 2001 From: Alastair Houghton Date: Fri, 29 Aug 2025 14:23:16 +0100 Subject: [PATCH 4/5] [Test][SwiftPM] Fix SwiftPM tests to run with `DYLD_LIBRARY_PATH` set. We need to tell SwiftPM's tests to run with `DYLD_LIBRARY_PATH` pointing to the new runtimes, otherwise they'll fail. --- .../swift_build_support/products/swiftpm.py | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/utils/swift_build_support/swift_build_support/products/swiftpm.py b/utils/swift_build_support/swift_build_support/products/swiftpm.py index ae2a45c8c6500..3129db8e2591f 100644 --- a/utils/swift_build_support/swift_build_support/products/swiftpm.py +++ b/utils/swift_build_support/swift_build_support/products/swiftpm.py @@ -11,6 +11,7 @@ # ---------------------------------------------------------------------------- import os +import platform from . import cmark from . import foundation @@ -23,7 +24,7 @@ from . import swift_testing from . import xctest from .. import shell -from ..targets import StdlibDeploymentTarget +from ..targets import StdlibDeploymentTarget, darwin_toolchain_prefix class SwiftPM(product.Product): @@ -50,6 +51,10 @@ def run_bootstrap_script( *, compile_only_for_running_host_architecture=False, ): + toolchain_path = _get_toolchain_path(host_target, self, self.args) + swift_lib_path = os.path.join(toolchain_path, + 'usr', 'lib', 'swift', 'macosx') + script_path = os.path.join( self.source_dir, 'Utilities', 'bootstrap') @@ -79,7 +84,8 @@ def run_bootstrap_script( "--cmake-path", self.toolchain.cmake, "--ninja-path", self.toolchain.ninja, "--build-dir", self.build_dir, - "--llbuild-build-dir", llbuild_build_dir + "--llbuild-build-dir", llbuild_build_dir, + "--extra-dynamic-library-path", swift_lib_path ] # Pass Dispatch directory down if we built it @@ -169,3 +175,16 @@ def get_dependencies(cls): xctest.XCTest, llbuild.LLBuild, swift_testing.SwiftTesting] + +def _get_toolchain_path(host_target, product, args): + # TODO check if we should prefer using product.install_toolchain_path + # this logic initially was inside run_build_script_helper + # and was factored out so it can be used in testing as well + + toolchain_path = product.host_install_destdir(host_target) + if platform.system() == 'Darwin': + # The prefix is an absolute path, so concatenate without os.path. + toolchain_path += \ + darwin_toolchain_prefix(args.install_prefix) + + return toolchain_path From 67395eb911d60662b3eb128567edf81eee8dc795 Mon Sep 17 00:00:00 2001 From: Alastair Houghton Date: Tue, 30 Sep 2025 16:19:53 +0100 Subject: [PATCH 5/5] [DNM] Always print a backtrace on cast failure. DO NOT MERGE. --- stdlib/public/runtime/Casting.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/stdlib/public/runtime/Casting.cpp b/stdlib/public/runtime/Casting.cpp index 254fdcc10669e..0ea3b72a47aa7 100644 --- a/stdlib/public/runtime/Casting.cpp +++ b/stdlib/public/runtime/Casting.cpp @@ -49,6 +49,11 @@ #include #endif +#ifdef __APPLE__ +#include +#include +#endif + using namespace swift; using namespace swift::hashable_support; using namespace metadataimpl; @@ -385,6 +390,19 @@ SWIFT_NORETURN SWIFT_NOINLINE void swift::swift_dynamicCastFailure(const void *sourceType, const char *sourceName, const void *targetType, const char *targetName, const char *message) { + #ifdef __APPLE__ + fprintf(stderr, "**** CAST FAILED ****"); + + void *addrs[256]; + int count = backtrace(addrs, 256); + + char **symbols = backtrace_symbols(addrs, count); + + for (int n = 0; n < count; ++n) { + fprintf(stderr, "%d %p: %s\n", n, addrs[n], symbols[n]); + } + #endif + swift::fatalError(/* flags = */ 0, "Could not cast value of type '%s' (%p) to '%s' (%p)%s%s\n", sourceName, sourceType,