diff options
Diffstat (limited to 'src/mscorlib/src/System/Threading/SpinLock.cs')
-rw-r--r-- | src/mscorlib/src/System/Threading/SpinLock.cs | 110 |
1 files changed, 25 insertions, 85 deletions
diff --git a/src/mscorlib/src/System/Threading/SpinLock.cs b/src/mscorlib/src/System/Threading/SpinLock.cs index dea87435a7..1d90890d6e 100644 --- a/src/mscorlib/src/System/Threading/SpinLock.cs +++ b/src/mscorlib/src/System/Threading/SpinLock.cs @@ -12,11 +12,11 @@ // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- using System; -using System.Diagnostics; using System.Security.Permissions; using System.Runtime.InteropServices; using System.Runtime.CompilerServices; using System.Runtime.ConstrainedExecution; +using System.Diagnostics; using System.Diagnostics.Contracts; namespace System.Threading @@ -55,7 +55,6 @@ namespace System.Threading /// </para> /// </remarks> [ComVisible(false)] - [HostProtection(Synchronization = true, ExternalThreading = true)] [DebuggerTypeProxy(typeof(SystemThreading_SpinLockDebugView))] [DebuggerDisplay("IsHeld = {IsHeld}")] public struct SpinLock @@ -107,7 +106,6 @@ namespace System.Threading // The waiters count is calculated by m_owner & WAITERS_MASK 01111....110 private static int MAXIMUM_WAITERS = WAITERS_MASK; - /// <summary> /// Initializes a new instance of the <see cref="T:System.Threading.SpinLock"/> /// structure with the option to track thread IDs to improve debugging. @@ -123,11 +121,10 @@ namespace System.Threading if (!enableThreadOwnerTracking) { m_owner |= LOCK_ID_DISABLE_MASK; - Contract.Assert(!IsThreadOwnerTrackingEnabled, "property should be false by now"); + Debug.Assert(!IsThreadOwnerTrackingEnabled, "property should be false by now"); } } - /// <summary> /// Initializes a new instance of the <see cref="T:System.Threading.SpinLock"/> /// structure with the option to track thread IDs to improve debugging. @@ -157,9 +154,6 @@ namespace System.Threading /// </exception> public void Enter(ref bool lockTaken) { -#if !FEATURE_CORECLR - Thread.BeginCriticalRegion(); -#endif //Try to keep the code and branching in this method as small as possible in order to inline the method int observedOwner = m_owner; if (lockTaken || //invalid parameter @@ -225,7 +219,7 @@ namespace System.Threading if (totalMilliseconds < -1 || totalMilliseconds > int.MaxValue) { throw new System.ArgumentOutOfRangeException( - "timeout", timeout, Environment.GetResourceString("SpinLock_TryEnter_ArgumentOutOfRange")); + nameof(timeout), timeout, Environment.GetResourceString("SpinLock_TryEnter_ArgumentOutOfRange")); } // Call reliable enter with the int-based timeout milliseconds @@ -256,10 +250,6 @@ namespace System.Threading /// a negative number other than -1, which represents an infinite time-out.</exception> public void TryEnter(int millisecondsTimeout, ref bool lockTaken) { -#if !FEATURE_CORECLR - Thread.BeginCriticalRegion(); -#endif - int observedOwner = m_owner; if (millisecondsTimeout < -1 || //invalid parameter lockTaken || //invalid parameter @@ -277,10 +267,6 @@ namespace System.Threading /// <param name="lockTaken">The lockTaken param</param> private void ContinueTryEnter(int millisecondsTimeout, ref bool lockTaken) { - //Leave the critical region which is entered by the fast path -#if !FEATURE_CORECLR - Thread.EndCriticalRegion(); -#endif // The fast path doesn't throw any exception, so we have to validate the parameters here if (lockTaken) { @@ -291,23 +277,15 @@ namespace System.Threading if (millisecondsTimeout < -1) { throw new ArgumentOutOfRangeException( - "millisecondsTimeout", millisecondsTimeout, Environment.GetResourceString("SpinLock_TryEnter_ArgumentOutOfRange")); + nameof(millisecondsTimeout), millisecondsTimeout, Environment.GetResourceString("SpinLock_TryEnter_ArgumentOutOfRange")); } - uint startTime = 0; if (millisecondsTimeout != Timeout.Infinite && millisecondsTimeout != 0) { startTime = TimeoutHelper.GetTime(); } -#if !FEATURE_CORECLR - if (CdsSyncEtwBCLProvider.Log.IsEnabled()) - { - CdsSyncEtwBCLProvider.Log.SpinLock_FastPathFailed(m_owner); - } -#endif - if (IsThreadOwnerTrackingEnabled) { // Slow path for enabled thread tracking mode @@ -333,18 +311,22 @@ namespace System.Threading observedOwner = m_owner; if ((observedOwner & LOCK_ANONYMOUS_OWNED) == LOCK_UNOWNED) { -#if !FEATURE_CORECLR - Thread.BeginCriticalRegion(); -#endif - 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 +334,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; @@ -377,32 +348,24 @@ namespace System.Threading observedOwner = m_owner; if ((observedOwner & LOCK_ANONYMOUS_OWNED) == LOCK_UNOWNED) { -#if !FEATURE_CORECLR - Thread.BeginCriticalRegion(); -#endif - int newOwner = (observedOwner & WAITERS_MASK) == 0 ? // Gets the number of waiters, if zero observedOwner | 1 // don't decrement it. just set the lock bit, it is zzero because a previous call of Exit(false) ehich corrupted the waiters : (observedOwner - 2) | 1; // otherwise decrement the waiters and set the lock bit - Contract.Assert((newOwner & WAITERS_MASK) >= 0); + Debug.Assert((newOwner & WAITERS_MASK) >= 0); if (Interlocked.CompareExchange(ref m_owner, newOwner, observedOwner, ref lockTaken) == observedOwner) { return; } - -#if !FEATURE_CORECLR - Thread.EndCriticalRegion(); -#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 @@ -413,22 +376,15 @@ namespace System.Threading observedOwner = m_owner; if ((observedOwner & LOCK_ANONYMOUS_OWNED) == LOCK_UNOWNED) { -#if !FEATURE_CORECLR - Thread.BeginCriticalRegion(); -#endif int newOwner = (observedOwner & WAITERS_MASK) == 0 ? // Gets the number of waiters, if zero observedOwner | 1 // don't decrement it. just set the lock bit, it is zzero because a previous call of Exit(false) ehich corrupted the waiters : (observedOwner - 2) | 1; // otherwise decrement the waiters and set the lock bit - Contract.Assert((newOwner & WAITERS_MASK) >= 0); + Debug.Assert((newOwner & WAITERS_MASK) >= 0); if (Interlocked.CompareExchange(ref m_owner, newOwner, observedOwner, ref lockTaken) == observedOwner) { return; } - -#if !FEATURE_CORECLR - Thread.EndCriticalRegion(); -#endif } if (yieldsoFar % SLEEP_ONE_FREQUENCY == 0) @@ -470,7 +426,7 @@ namespace System.Threading if ((observedOwner & WAITERS_MASK) == 0) return; // don't decrement the waiters if it's corrupted by previous call of Exit(false) if (Interlocked.CompareExchange(ref m_owner, observedOwner - 2, observedOwner) == observedOwner) { - Contract.Assert(!IsThreadOwnerTrackingEnabled); // Make sure the waiters never be negative which will cause the thread tracking bit to be flipped + Debug.Assert(!IsThreadOwnerTrackingEnabled); // Make sure the waiters never be negative which will cause the thread tracking bit to be flipped break; } spinner.SpinOnce(); @@ -483,7 +439,7 @@ namespace System.Threading /// </summary> private void ContinueTryEnterWithThreadTracking(int millisecondsTimeout, uint startTime, ref bool lockTaken) { - Contract.Assert(IsThreadOwnerTrackingEnabled); + Debug.Assert(IsThreadOwnerTrackingEnabled); int lockUnowned = 0; // We are using thread IDs to mark ownership. Snap the thread ID and check for recursion. @@ -510,17 +466,10 @@ namespace System.Threading if (m_owner == lockUnowned) { -#if !FEATURE_CORECLR - Thread.BeginCriticalRegion(); -#endif if (Interlocked.CompareExchange(ref m_owner, m_newOwner, lockUnowned, ref lockTaken) == lockUnowned) { return; } -#if !FEATURE_CORECLR - // The thread failed to get the lock, so we don't need to remain in a critical region. - Thread.EndCriticalRegion(); -#endif } // Check the timeout. We only RDTSC if the next spin will yield, to amortize the cost. if (millisecondsTimeout == 0 || @@ -550,11 +499,6 @@ namespace System.Threading ExitSlowPath(true); else Interlocked.Decrement(ref m_owner); - -#if !FEATURE_CORECLR - Thread.EndCriticalRegion(); -#endif - } /// <summary> @@ -586,10 +530,6 @@ namespace System.Threading } else ExitSlowPath(useMemoryBarrier); - -#if !FEATURE_CORECLR - Thread.EndCriticalRegion(); -#endif } /// <summary> |