Skip to content

Commit 7bd31ac

Browse files
kouveljkotas
authored andcommitted
Don't Sleep(1) in some spin-wait loops (dotnet#21722)
- In spin-wait loops that are not expected to last too long, Sleep(1) significantly delays threads from completing the operation - From eliminating Sleep(1) in such spin-wait loops, there can be a tradeoff, better fairness vs worse throughput, because Sleep(1) removes threads from contention and in some cases fewer threads can make faster progress at the cost of delaying the Sleep(1) threads relatively significantly. Eliminating the Sleep(1) in such spin-wait loops seems to be a good tradeoff.
1 parent bac3ac8 commit 7bd31ac

File tree

3 files changed

+5
-15
lines changed

3 files changed

+5
-15
lines changed

src/System.Private.CoreLib/shared/System/Collections/Concurrent/ConcurrentQueueSegment.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ public bool TryDequeue(out T item)
193193
}
194194

195195
// Lost a race. Spin a bit, then try again.
196-
spinner.SpinOnce();
196+
spinner.SpinOnce(sleep1Threshold: -1);
197197
}
198198
}
199199

@@ -254,7 +254,7 @@ public bool TryPeek(out T result, bool resultUsed)
254254
}
255255

256256
// Lost a race. Spin a bit, then try again.
257-
spinner.SpinOnce();
257+
spinner.SpinOnce(sleep1Threshold: -1);
258258
}
259259
}
260260

@@ -311,7 +311,7 @@ public bool TryEnqueue(T item)
311311
}
312312

313313
// Lost a race. Spin a bit, then try again.
314-
spinner.SpinOnce();
314+
spinner.SpinOnce(sleep1Threshold: -1);
315315
}
316316
}
317317

src/System.Private.CoreLib/shared/System/Threading/ManualResetEventSlim.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,7 @@ public bool Wait(int millisecondsTimeout, CancellationToken cancellationToken)
551551
var spinner = new SpinWait();
552552
while (spinner.Count < spinCount)
553553
{
554-
spinner.SpinOnce(SpinWait.Sleep1ThresholdForLongSpinBeforeWait);
554+
spinner.SpinOnce(sleep1Threshold: -1);
555555

556556
if (IsSet)
557557
{
@@ -720,7 +720,7 @@ private void UpdateStateAtomically(int newBits, int updateBitsMask)
720720
return;
721721
}
722722

723-
sw.SpinOnce();
723+
sw.SpinOnce(sleep1Threshold: -1);
724724
} while (true);
725725
}
726726

src/System.Private.CoreLib/shared/System/Threading/SpinWait.cs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -89,16 +89,6 @@ public struct SpinWait
8989
/// </remarks>
9090
internal static readonly int SpinCountforSpinBeforeWait = PlatformHelper.IsSingleProcessor ? 1 : 35;
9191

92-
/// <summary>
93-
/// Typically, Sleep(1) should not be issued for a spin-wait before a proper wait because it is usually more beneficial
94-
/// to just issue the proper wait. For longer spin-waits (when the spin count is configurable), this value may be used as
95-
/// a threshold for issuing Sleep(1).
96-
/// </summary>
97-
/// <remarks>
98-
/// Should be greater than <see cref="SpinCountforSpinBeforeWait"/> so that Sleep(1) would not be used by default.
99-
/// </remarks>
100-
internal const int Sleep1ThresholdForLongSpinBeforeWait = 40;
101-
10292
// The number of times we've spun already.
10393
private int _count;
10494

0 commit comments

Comments
 (0)