-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Description
SpinWait.SpinOnce has always used a fixed threshold before which it would start to call Thread.Sleep(1).
The jump in delay from spinning/Sleep(0) to a Sleep(1) is many orders in magnitude, and no single threshold will be good for every spinning usage scenario. An internal overload was added to allow specifying the Sleep(1) threshold in some places where we already encountered this issue:
In some cases, the scenario may also prefer to disable Sleep(1) altogether, for instance in Interlocked.CompareExchange() loops, see https://github.com/dotnet/corefx/issues/29595. Also, when a proper wait follows the spinning, the spin loop typically should not do Sleep(1) as doing the proper wait is usually better, for example:
ManualResetEventSlim- the code here effectively disablesSleep(1)during the spinning due to thisSemaphoreSlim
Proposed API
public struct SpinWait
{
public void SpinOnce(int minimumSleep1SpinCountThreshold) { }
}minimumSleep1SpinCountThreshold:
< -1:ArgumentOutOfRangeException== -1:Sleep(1)will not be used>= 0: Specifies a minimum spin count after whichSleep(1)may be used based on unspecified heuristics- For the implementation, we could probably make the value have a minimum of
SpinWait.YieldThresholdsuch that the value returned bySpinWait.NextSpinWillYieldwould still be somewhat meaningful
- For the implementation, we could probably make the value have a minimum of
- Not sure about the name, suggestions?
Alternatives
Add a field for the Sleep(1) threshold to SpinWait and a constructor overload to set it.
- Effects of increasing its size are unknown and could have undesired side-effects