-
-
Notifications
You must be signed in to change notification settings - Fork 14.8k
Waker::will_wake() gets mostly defeated by executor optimizations #66281
Copy link
Copy link
Open
Labels
A-async-awaitArea: Async & AwaitArea: Async & AwaitAsyncAwait-TriagedAsync-await issues that have been triaged during a working group meeting.Async-await issues that have been triaged during a working group meeting.C-enhancementCategory: An issue proposing an enhancement or a PR with one.Category: An issue proposing an enhancement or a PR with one.C-optimizationCategory: An issue highlighting optimization opportunities or PRs implementing suchCategory: An issue highlighting optimization opportunities or PRs implementing suchT-libs-apiRelevant to the library API team, which will review and decide on the PR/issue.Relevant to the library API team, which will review and decide on the PR/issue.
Metadata
Metadata
Assignees
Labels
A-async-awaitArea: Async & AwaitArea: Async & AwaitAsyncAwait-TriagedAsync-await issues that have been triaged during a working group meeting.Async-await issues that have been triaged during a working group meeting.C-enhancementCategory: An issue proposing an enhancement or a PR with one.Category: An issue proposing an enhancement or a PR with one.C-optimizationCategory: An issue highlighting optimization opportunities or PRs implementing suchCategory: An issue highlighting optimization opportunities or PRs implementing suchT-libs-apiRelevant to the library API team, which will review and decide on the PR/issue.Relevant to the library API team, which will review and decide on the PR/issue.
Type
Fields
Give feedbackNo fields configured for issues without a type.
The Futures
WakerAPI provides a Waker::will_wake() method which tries to determine whether the 2Wakers are equivalent. It intends to allowFutures so determine whether they have to swap aWakeror have to can keep an already stored one which is equivalent. That can avoid some churn on atomic refcounts on thoseWakers.The
will_wakemethod is implemented by aPartialEqderive onRawWaker- which meanswill_wake()will returntrueonly if the pointer as well as the vtable inRawWakerare equivalent.However futures executors are moving more and more towards a design where they lazily create the "real" storeable
Waker, and only provide aWakerreference to tasks they poll. E.g.futures-rsuses WakerRef tokio does the same. This avoids an atomic increment and decrement cycle for each task that an executor polls.However this means the
RawWakerthat the executor passes through theContextparameter will now always be different to the one stored inside aFutureandwill_wake()will return false. Which causes theFutureto update theWakerreference (2 atomic ops). If the executor polls a couple of sub-tasks which now all swap out theirWakers the original executor optimization could now even lead to de-optimization - since the result is more atomic ops in other places.Using the
will_wake()method makes most sense exactly inside the.poll()method of aFuturein order to determine whether a storedWakerneeds to get updated. This is now the exact same point where theWakerRefwould return the false negative. Therefore using.will_wake()is not that helpful given the state of the executor ecosystem.So far for the description of the issue. The next question is whether this can be improved or solved. I don't think changing
PartialEq for RawWaker- e.g. to conly compare the data pointer - makes sense. It will likely only lead to false positives (waker.will_wake(other) == true). Which then leads to missing wakeups aka live-locks.The original design of
RawWakerplusVtablecontained a vtable entry forwill_wake(). This would have definitely helped to solve the issue, since the executors would have been able to overwrite the check and to be able to associateWakers and theirWakerRefs. However this was removed for simplification purposes.I think one possible outcome could be to keep this issue as a tracking issue for the deficit. And if there is ever a change to the vtable for other reasons to also add a
will_wakemethod back. Up to then it's probably not worth an update.