-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Initial Task Executor implementation Task(on:), addTask(on:) etc. #68793
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
0536cc0
to
887f9f6
Compare
887f9f6
to
c0f8daf
Compare
f18f19d
to
e6ad086
Compare
8d7549b
to
5bcff28
Compare
@swift-ci please build toolchain |
5bcff28
to
77371a9
Compare
@swift-ci please build toolchain macOS |
313a0bc
to
16e138e
Compare
@swift-ci please smoke test |
@swift-ci please build toolchain macOS |
16e138e
to
c164dc1
Compare
@swift-ci please smoke test |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Leaving off there for now
include/swift/ABI/Task.h
Outdated
/// setting it during creation (`Task(on:...)`). | ||
/// | ||
/// This means that during task tear down the record should be deallocated | ||
/// because it was not set with a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another unfinished comme
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, fixed in 63c8f01 and looked at all other comments as well.
/// Build a Builtin.Executor value from an "ordinary" task executor | ||
/// reference. | ||
BUILTIN_MISC_OPERATION_WITH_SILGEN(BuildOrdinaryTaskExecutorRef, | ||
"buildOrdinaryTaskExecutorRef", "n", Special) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you end up needing these builtins for some reason?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
edit; Yes we need those because:
struct UnownedTaskExecutor {
// ...
@inlinable
public init<E: TaskExecutor>(ordinary executor: __shared E) {
// ...
self.executor = Builtin.buildOrdinaryTaskExecutorRef(executor)
which is different from the UnownedSerialExecutor; even though they both just store the "...Ref" style reference that's opaque in Swift. If we had different flags for Task executor than for Serial executor or something this entry points matters.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Github seems to have lost my comment -- yes, we need these because:
struct UnownedTaskExecutor {
@inlinable
public init<E: TaskExecutor>(ordinary executor: __shared E) {
#if $BuiltinBuildTaskExecutor
self.executor = Builtin.buildOrdinaryTaskExecutorRef(executor)
#else
fatalError("Swift compiler is incompatible with this SDK version")
#endif
}
}
We arguably could "wing it" and use the buildOrdinaryExecutorRef
though I'm unsure about the proliferation of pretending as if they're the same... Internally the representation is the same though, that is true -- the memory layout of SerialExecutorRef and TaskExecutorRef is the same, at least currently.
include/swift/Runtime/Concurrency.h
Outdated
@@ -900,6 +918,20 @@ SerialExecutorRef swift_task_getCurrentExecutor(void); | |||
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift) | |||
SerialExecutorRef swift_task_getMainExecutor(void); | |||
|
|||
/// Return the generic (default global concurrent) executor reference. | |||
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift) | |||
SerialExecutorRef swift_task_getGenericExecutor(void); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you're adding these new functions to the runtime ABI, please note which Swift release added them.
But this function in particular I think we don't need — there's an ABI-guaranteed way of constructing this already (IIRC it's the all-zeroes value).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okey, yeah I wasn't sure if we want to hardcode this assumption here -- you are right that it is guaranteed currently to be a {0, 0}
basically (SerialExecutorRef), so okey if we want to assume this I removed the function and replaced it with:
@available(SwiftStdlib 9999, *)
@usableFromInline
internal func _getGenericSerialExecutor() -> Builtin.Executor {
// The `SerialExecutorRef` to "default generic executor" is guaranteed
// to be a zero value;
//
// As the runtime relies on this in multiple places,
// so instead of a runtime call to get this executor ref, we bitcast a "zero"
// of expected size to the builtin executor type.
unsafeBitCast((UInt(0), UInt(0)), to: Builtin.Executor.self)
}
Is that the right UInt to use here...? In C++ it is:
HeapObject *Identity; // Not necessarily Swift reference-countable
uintptr_t Implementation;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did the same for _getUndefinedTaskExecutor
as well, to avoid runtime calls: 1318d3e
include/swift/Runtime/Concurrency.h
Outdated
/// It can be used used to store a record indicating that | ||
/// there is no task executor preference in the current scope. | ||
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift) | ||
TaskExecutorRef swift_task_getUndefinedTaskExecutor(void); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similarly, I don't think we need a function for this, because we really want this to be guaranteed to be the all-zeroes value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okey gotcha so I'll just bitcast zeroes and avoid the runtime call. Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, and removed the runtime func -- explained more here: #68793 (comment)
TaskExecutorRef swift_task_getUndefinedTaskExecutor(void); | ||
|
||
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift) | ||
TaskExecutorRef swift_task_getPreferredTaskExecutor(void); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This really needs documentation explaining the constraints on how it can be used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added in: 10cadfa I think that covers the "be careful" side of things. Anything more we should add?
These were added in earlier commits of the initial task executor work, however they are not necessary after all -- we get the right hop behavior just from the task executor stored and picked up in runtime functions already.
53ef9d7
to
43a8924
Compare
43a8924
to
907b0e6
Compare
|
@swift-ci please smoke test |
@swift-ci please smoke test macOS |
…iftlang#68793) Co-authored-by: John McCall <[email protected]>
Pending proposal and Swift Evolution process, do not merge yet.
This generally will allow tasks to be launched/spawned immediately on a specific executor or actor, and handle all the associated isolation.
Resolves rdar://107072140