diff --git a/include/swift/Basic/Features.def b/include/swift/Basic/Features.def index e10ab52cf4a..932c0711bcc 100644 --- a/include/swift/Basic/Features.def +++ b/include/swift/Basic/Features.def @@ -277,6 +277,7 @@ LANGUAGE_FEATURE(LifetimeDependenceMutableAccessors, 0, "Support mutable accesso LANGUAGE_FEATURE(InoutLifetimeDependence, 0, "Support @_lifetime(&)") SUPPRESSIBLE_LANGUAGE_FEATURE(NonexhaustiveAttribute, 487, "Nonexhaustive Enums") LANGUAGE_FEATURE(ModuleSelector, 491, "Module selectors (`Module::name` syntax)") +LANGUAGE_FEATURE(BuiltinConcurrencyStackNesting, 0, "Concurrency Stack Nesting Builtins") // Swift 6 UPCOMING_FEATURE(ConciseMagicFile, 274, 6) diff --git a/lib/AST/FeatureSet.cpp b/lib/AST/FeatureSet.cpp index 4e6de42c78d..c5501b2b100 100644 --- a/lib/AST/FeatureSet.cpp +++ b/lib/AST/FeatureSet.cpp @@ -350,6 +350,10 @@ static bool usesFeatureClosureBodyMacro(Decl *decl) { return false; } +static bool usesFeatureBuiltinConcurrencyStackNesting(Decl *decl) { + return false; +} + UNINTERESTING_FEATURE(StrictMemorySafety) UNINTERESTING_FEATURE(LibraryEvolution) UNINTERESTING_FEATURE(SafeInteropWrappers) diff --git a/stdlib/public/Concurrency/Task+PriorityEscalation.swift b/stdlib/public/Concurrency/Task+PriorityEscalation.swift index d488f58b8c2..40824cf2d0f 100644 --- a/stdlib/public/Concurrency/Task+PriorityEscalation.swift +++ b/stdlib/public/Concurrency/Task+PriorityEscalation.swift @@ -125,11 +125,30 @@ func __withTaskPriorityEscalationHandler0( onPriorityEscalated handler0: @Sendable (UInt8, UInt8) -> Void, isolation: isolated (any Actor)? = #isolation ) async throws(E) -> T { +#if $BuiltinConcurrencyStackNesting let record = unsafe Builtin.taskAddPriorityEscalationHandler(handler: handler0) defer { unsafe Builtin.taskRemovePriorityEscalationHandler(record: record) } +#else + let record = unsafe _taskAddPriorityEscalationHandler(handler: handler0) + defer { unsafe _taskRemovePriorityEscalationHandler(record: record) } +#endif return try await operation() } + +@usableFromInline +@available(SwiftStdlib 6.2, *) +@_silgen_name("swift_task_addPriorityEscalationHandler") +func _taskAddPriorityEscalationHandler( + handler: (UInt8, UInt8) -> Void +) -> UnsafeRawPointer /*EscalationNotificationStatusRecord*/ + +@usableFromInline +@available(SwiftStdlib 6.2, *) +@_silgen_name("swift_task_removePriorityEscalationHandler") +func _taskRemovePriorityEscalationHandler( + record: UnsafeRawPointer /*EscalationNotificationStatusRecord*/ +) diff --git a/stdlib/public/Concurrency/TaskCancellation.swift b/stdlib/public/Concurrency/TaskCancellation.swift index b4d453e7265..5c24671fb13 100644 --- a/stdlib/public/Concurrency/TaskCancellation.swift +++ b/stdlib/public/Concurrency/TaskCancellation.swift @@ -84,9 +84,13 @@ public func withTaskCancellationHandler( ) async rethrows -> T { // unconditionally add the cancellation record to the task. // if the task was already cancelled, it will be executed right away. +#if $BuiltinConcurrencyStackNesting let record = unsafe Builtin.taskAddCancellationHandler(handler: handler) defer { unsafe Builtin.taskRemoveCancellationHandler(record: record) } - +#else + let record = unsafe _taskAddCancellationHandler(handler: handler) + defer { unsafe _taskRemoveCancellationHandler(record: record) } +#endif return try await operation() } @@ -105,9 +109,13 @@ public func _unsafeInheritExecutor_withTaskCancellationHandler( ) async rethrows -> T { // unconditionally add the cancellation record to the task. // if the task was already cancelled, it will be executed right away. +#if $BuiltinConcurrencyStackNesting let record = unsafe Builtin.taskAddCancellationHandler(handler: handler) defer { unsafe Builtin.taskRemoveCancellationHandler(record: record) } - +#else + let record = unsafe _taskAddCancellationHandler(handler: handler) + defer { unsafe _taskRemoveCancellationHandler(record: record) } +#endif return try await operation() } @@ -163,3 +171,16 @@ public struct CancellationError: Error { // no extra information, cancellation is intended to be light-weight public init() {} } + +@usableFromInline +@available(SwiftStdlib 5.1, *) +@_silgen_name("swift_task_addCancellationHandler") +func _taskAddCancellationHandler(handler: () -> Void) -> UnsafeRawPointer /*CancellationNotificationStatusRecord*/ + +@usableFromInline +@available(SwiftStdlib 5.1, *) +@_silgen_name("swift_task_removeCancellationHandler") +func _taskRemoveCancellationHandler( + record: UnsafeRawPointer /*CancellationNotificationStatusRecord*/ +) + diff --git a/stdlib/public/Concurrency/TaskLocal.swift b/stdlib/public/Concurrency/TaskLocal.swift index bf9f9e1a1b0..256627880e9 100644 --- a/stdlib/public/Concurrency/TaskLocal.swift +++ b/stdlib/public/Concurrency/TaskLocal.swift @@ -259,8 +259,13 @@ public final class TaskLocal: Sendable, CustomStringConvertible operation: () async throws -> R, isolation: isolated (any Actor)?, file: String = #fileID, line: UInt = #line) async rethrows -> R { +#if $BuiltinConcurrencyStackNesting Builtin.taskLocalValuePush(key, consume valueDuringOperation) defer { Builtin.taskLocalValuePop() } +#else + _taskLocalValuePush(key: key, value: consume valueDuringOperation) + defer { _taskLocalValuePop() } +#endif return try await operation() } @@ -275,8 +280,13 @@ public final class TaskLocal: Sendable, CustomStringConvertible operation: () async throws -> R, file: String = #fileID, line: UInt = #line ) async rethrows -> R { +#if $BuiltinConcurrencyStackNesting Builtin.taskLocalValuePush(key, consume valueDuringOperation) defer { Builtin.taskLocalValuePop() } +#else + _taskLocalValuePush(key: key, value: consume valueDuringOperation) + defer { _taskLocalValuePop() } +#endif return try await operation() } @@ -299,8 +309,13 @@ public final class TaskLocal: Sendable, CustomStringConvertible @discardableResult public func withValue(_ valueDuringOperation: Value, operation: () throws -> R, file: String = #fileID, line: UInt = #line) rethrows -> R { +#if $BuiltinConcurrencyStackNesting Builtin.taskLocalValuePush(key, valueDuringOperation) defer { Builtin.taskLocalValuePop() } +#else + _taskLocalValuePush(key: key, value: valueDuringOperation) + defer { _taskLocalValuePop() } +#endif return try operation() } @@ -344,6 +359,19 @@ public final class TaskLocal: Sendable, CustomStringConvertible // ==== ------------------------------------------------------------------------ +@available(SwiftStdlib 5.1, *) +@usableFromInline +@_silgen_name("swift_task_localValuePush") +func _taskLocalValuePush( + key: Builtin.RawPointer/*: Key*/, + value: __owned Value +) // where Key: TaskLocal + +@available(SwiftStdlib 5.1, *) +@usableFromInline +@_silgen_name("swift_task_localValuePop") +func _taskLocalValuePop() + @available(SwiftStdlib 5.1, *) @_silgen_name("swift_task_localValueGet") func _taskLocalValueGet(