Skip to content

Commit c882224

Browse files
authored
Fix stack size variance between iterations (#3064)
* Fix stack size variance between iterations. * Check cancellation after yield. * Fix test
1 parent 7aa9759 commit c882224

File tree

2 files changed

+8
-5
lines changed

2 files changed

+8
-5
lines changed

src/BenchmarkDotNet/Engines/Engine.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using BenchmarkDotNet.Attributes.CompilerServices;
1+
using BenchmarkDotNet.Attributes.CompilerServices;
22
using BenchmarkDotNet.Characteristics;
33
using BenchmarkDotNet.Helpers;
44
using BenchmarkDotNet.Jobs;
@@ -89,16 +89,19 @@ public async ValueTask<RunResults> RunAsync()
8989
}
9090

9191
// This method is extra long because the helper methods were inlined in order to prevent extra async allocations on each iteration.
92-
private async ValueTask<RunResults> RunCore()
92+
private async Task<RunResults> RunCore()
9393
{
94+
// We need to force an async yield here to ensure each benchmark invocation is called with a constant stack size. #1120
95+
await Task.Yield();
96+
Host.CancellationToken.ThrowIfCancellationRequested();
97+
9498
var measurements = new List<Measurement>();
9599

96100
if (EngineEventSource.Log.IsEnabled())
97101
EngineEventSource.Log.BenchmarkStart(Parameters.BenchmarkName);
98102

99103
IterationData extraIterationData = default;
100-
// Enumerate the stages and run iterations in a loop to ensure each benchmark invocation is called with a constant stack size.
101-
// #1120
104+
// Enumerate the stages and run iterations in a loop to ensure each benchmark invocation is called with a constant stack size. #1120
102105
foreach (var stage in EngineStage.EnumerateStages(Parameters))
103106
{
104107
if (stage.Stage == IterationStage.Actual && stage.Mode == IterationMode.Workload)

src/BenchmarkDotNet/Toolchains/InProcess/NoEmit/InProcessNoEmitRunner.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public static async ValueTask<int> Run(IHost host, ExecuteParameters parameters,
3636

3737
var methodInfo = type.GetMethod(nameof(Runnable.RunCore), BindingFlags.Public | BindingFlags.Static)
3838
?? throw new InvalidOperationException($"Bug: method {nameof(Runnable.RunCore)} in {inProcessRunnableTypeName} not found.");
39-
await ((ValueTask) methodInfo.Invoke(null, [host, parameters, benchmarkActionFactory])!).ConfigureAwait(false);
39+
await ((ValueTask) methodInfo.Invoke(null, [host, parameters, benchmarkActionFactory])!).ConfigureAwait(true);
4040

4141
return 0;
4242
}

0 commit comments

Comments
 (0)