-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Introduce basic support for custom executors #36878
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
@swift-ci Please test |
Build failed |
Build failed |
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'm in no position to provide useful feedback on impl I guess, but read through and at least much more of it nowadays I understood :)
Some minor questions in line... only if you have the time, nothing urgent. Looking great overall!
c656072
to
dca5f22
Compare
@swift-ci Please test |
Build failed |
Build failed |
dca5f22
to
6240c73
Compare
@swift-ci Please test |
Build failed |
Build failed |
6240c73
to
374b29a
Compare
@swift-ci Please test |
Build failed |
lib/SILGen/SILGenType.cpp
Outdated
@@ -59,8 +59,13 @@ SILGenModule::emitVTableMethod(ClassDecl *theClass, | |||
// case we won't emit it if building a resilient module. | |||
SILVTable::Entry::Kind implKind; | |||
if (baseClass == theClass) { | |||
// This is a vtable entry for a method of the immediate class. | |||
implKind = SILVTable::Entry::Kind::Normal; | |||
if (derivedDecl->isResilientFinal()) |
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.
Can you reuse isNonOverridden
here instead of adding a new SILVTable entry kind? I had started by trying to add a new kind, but I ended up needing to make the attribute orthogonal.
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.
Can you remember why? The modeling seems much cleaner this way.
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 don't completely remember the specifics, but the distinction between Normal
and Inherited
is significant, and when a method has no overrides but the class does have other subclasses, then it is perfectly valid to have an entry that is both inherited and non-overridden in the subclass.
|
@swift-ci Please test |
How do you feel this is distinguished? Just because it (might) forbid Remember that we want to support back-deployment in short order, so that seems like a constraint we can't ignore. |
Build failed |
IIRC method descriptors are also referenced by external subclasses so we can resiliently build their vtable; would that ever be a concern here? To be clear, I don't think the backward deployment support here is particularly onerous; I had planned to address it in the linked PR by linking in a lookup method implementation that just does the "is nonoverridden" check first then forwards to the OS implementation. |
ebfcb3a
to
fcb9901
Compare
@swift-ci Please test |
I think we only do this with overrides, and of course these aren't overridable. I don't think you can safely back-deploy an override in any case. The existing runtime seems to I do see what I think is your point: that we don't semantically prevent I wonder if it would be feasible to treat this as a language defect and ban |
Build failed |
But your goal here is to allow this to become overridable in the future, no? Otherwise it would just be |
5b9257c
to
6ac1f15
Compare
@swift-ci Please test |
Build failed |
Build failed |
6ac1f15
to
6cea747
Compare
@swift-ci Please test |
Build failed |
- Introduce an UnownedSerialExecutor type into the concurrency library. - Create a SerialExecutor protocol which allows an executor type to change how it executes jobs. - Add an unownedExecutor requirement to the Actor protocol. - Change the ABI for ExecutorRef so that it stores a SerialExecutor witness table pointer in the implementation field. This effectively makes ExecutorRef an `unowned(unsafe) SerialExecutor`, except that default actors are represented without a witness table pointer (just a bit-pattern). - Synthesize the unownedExecutor method for default actors (i.e. actors that don't provide an unownedExecutor property). - Make synthesized unownedExecutor properties `final`, and give them a semantics attribute specifying that they're for default actors. - Split `Builtin.buildSerialExecutorRef` into a few more precise builtins. We're not using the main-actor one yet, though. Pitch thread: https://forums.swift.org/t/support-custom-executors-in-swift-concurrency/44425
and traffic in Optional<Builtin.Executor> in various places.
Previously, they were storing a low-bit flag that indicated that they were a default actor. Using an extra inhabitant frees up the low bit for future use without being conspicuously more expensive to check.
6cea747
to
565198e
Compare
@swift-ci Please test |
@swift-ci Please clean test Windows |
I had to kill the Windows+VS2017 CI job that was testing this because it was stuck executing the custom_executors.swift test. It has been 6 hours, when normally the builds are around 1 hour. Just FYI. It might probably get stuck again. I might disable the test in Windows+VS2017 during the weekend. |
I've also merged this into the concurrency-5.5-abi-2 branch. |
Damn. The Windows bot was broken earlier, and I just had to hope that that wasn't masking a bug, but I guess it didn't work out. I can't debug the problem, but I'll look the code over to see if I can figure it out by inspection. |
Opened #37200 to disable the test on Windows. IIUC there are several major bugs in the Windows concurrency support that cause this kind of test failure. |
It seems to have been working OK for two builds in a row. It is probably flaky, but not that flaky. I haven't look, but I imagine it is not a logic error, but a small race in the Windows implementation that would be hard to figure out without a lot of trying. It is fine disabling it so it is less noise. |
UnownedSerialExecutor
type into the concurrency library.SerialExecutor
protocol which allows an executor type to change how it executes jobs.unownedExecutor
requirement to theActor
protocol.Builtin.Executor
(akaExecutorRef
, akaUnownedSerialExecutor
) so that it stores aSerialExecutor
witness table pointer in the implementation field. This effectively makes the type anunowned(unsafe) SerialExecutor
, except that default actors are represented without a witness table pointer.unownedExecutor
method for default actors (i.e. actors that don't provide any other execution logic).@_resilientFinal
, and give them a semantics attribute specifying that they're for default actors.Builtin.buildSerialExecutorRef
into a few more precise builtins. We're not using the main-actor one yet, though.Pitch thread: https://forums.swift.org/t/support-custom-executors-in-swift-concurrency/44425