From 0855b70b2542de60592cba7fe1c91bedb55566f4 Mon Sep 17 00:00:00 2001 From: Ben Adams Date: Fri, 14 Oct 2016 15:19:41 +0100 Subject: [PATCH] SpinLock.TryEnter fail fast for timeout 0 (#6952) * SpinLock.TryEnter fail fast for timeout 0 (2) * Don't over check SpinLock timeout When 1ms unlikely to have passed --- src/mscorlib/src/System/Threading/SpinLock.cs | 35 ++++++++++++++------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/src/mscorlib/src/System/Threading/SpinLock.cs b/src/mscorlib/src/System/Threading/SpinLock.cs index dea8743..9f5cf68 100644 --- a/src/mscorlib/src/System/Threading/SpinLock.cs +++ b/src/mscorlib/src/System/Threading/SpinLock.cs @@ -339,12 +339,23 @@ namespace System.Threading if (Interlocked.CompareExchange(ref m_owner, observedOwner | 1, observedOwner, ref lockTaken) == observedOwner) { + // Aquired lock return; } #if !FEATURE_CORECLR Thread.EndCriticalRegion(); #endif + if (millisecondsTimeout == 0) + { + // Did not aquire lock in CompareExchange and timeout is 0 so fail fast + return; + } + } + else if (millisecondsTimeout == 0) + { + // Did not aquire lock as owned and timeout is 0 so fail fast + return; } else //failed to acquire the lock,then try to update the waiters. If the waiters count reached the maximum, jsut break the loop to avoid overflow { @@ -352,17 +363,6 @@ namespace System.Threading turn = (Interlocked.Add(ref m_owner, 2) & WAITERS_MASK) >> 1 ; } - - - // Check the timeout. - if (millisecondsTimeout == 0 || - (millisecondsTimeout != Timeout.Infinite && - TimeoutHelper.UpdateTimeOut(startTime, millisecondsTimeout) <= 0)) - { - DecrementWaiters(); - return; - } - //***Step 2. Spinning //lock acquired failed and waiters updated int processorCount = PlatformHelper.ProcessorCount; @@ -396,15 +396,16 @@ namespace System.Threading #endif } } - } - // Check the timeout. - if (millisecondsTimeout != Timeout.Infinite && TimeoutHelper.UpdateTimeOut(startTime, millisecondsTimeout) <= 0) - { - DecrementWaiters(); - return; + // Check the timeout. + if (millisecondsTimeout != Timeout.Infinite && TimeoutHelper.UpdateTimeOut(startTime, millisecondsTimeout) <= 0) + { + DecrementWaiters(); + return; + } } + //*** Step 3, Yielding //Sleep(1) every 50 yields int yieldsoFar = 0; -- 2.7.4