Commit 0ffb238
authored
Rework
There was a subtle behavior difference between runtime async and async1
continuations when multiple of them were registered on a task. For
async1, `Task.RunContinuations` will run async1 continuations except the
first one in parallel, and then synchronously invoke the first one.
However, for runtime async we were using `ITaskCompletionAction` in this
case. This has different behavior: when multiple of these are present
they are all invoked sequentially. See the test introduced in this PR
(which was based on
[this](https://github.com/dotnet/runtime/blob/4e4d02afbe0b8144c8b3c8f1fdf25cacf5663b3c/src/libraries/System.Runtime/tests/System.Threading.Tasks.Tests/System.Runtime.CompilerServices/TaskAwaiterTests.cs#L182-L186)
test).
This PR fixes the problem by making `TaskContinuation` the continuation
object registered on `Task` instances, instead of `RuntimeAsyncTask`. To
that end rename the class to `RuntimeAsyncTaskContinuation` and teach
`Task.RunContinuations` about this kind of continuation. It differs from
`ITaskCompletionAction` in that all such instances are run in parallel,
with only the first instance being invoked synchronously.
Then consistently use this object as the continuation object for task
awaits. This is done for both `AsyncHelpers.TransparentAwait` and
`AsyncHelpers.Await`, so all `Await` calls are changed to use similar
task-caching optimization as we were doing for value task awaits before.
In addition optimize them in several ways:
- Teach the JIT to allow inlining of async functions when all awaits are
tail awaits (using `AsyncHelpers.TailAwait`)
- Rewrite all await helpers in the tail await shape to allow inlining of
them
- Optimize all await paths to use hand rolled continuations with caching
and that avoids additional async1 continuation allocationsAsyncHelpers await helpers for correctness and efficiency (#128528)1 parent ac7b8a0 commit 0ffb238
18 files changed
Lines changed: 725 additions & 221 deletions
File tree
- src
- coreclr
- System.Private.CoreLib
- src/System/Runtime/CompilerServices
- debug/di
- interpreter
- jit
- nativeaot/System.Private.CoreLib/src
- tools/Common/TypeSystem/IL/Stubs
- vm
- libraries/System.Private.CoreLib/src/System
- Runtime/CompilerServices
- Threading/Tasks
- tests/async/parallel-continuations
Lines changed: 4 additions & 4 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
206 | 206 | | |
207 | 207 | | |
208 | 208 | | |
209 | | - | |
210 | | - | |
| 209 | + | |
211 | 210 | | |
| 211 | + | |
212 | 212 | | |
213 | 213 | | |
214 | 214 | | |
| |||
292 | 292 | | |
293 | 293 | | |
294 | 294 | | |
295 | | - | |
| 295 | + | |
296 | 296 | | |
297 | 297 | | |
298 | 298 | | |
| |||
311 | 311 | | |
312 | 312 | | |
313 | 313 | | |
314 | | - | |
| 314 | + | |
315 | 315 | | |
316 | 316 | | |
317 | 317 | | |
| |||
0 commit comments