10 [DebuggerTypeProxy(typeof(SystemThreading_SpinLockDebugView))]
11 [DebuggerDisplay(
"IsHeld = {IsHeld}")]
12 [__DynamicallyInvokable]
13 [HostProtection(
SecurityAction.LinkDemand, Synchronization =
true, ExternalThreading =
true)]
16 internal class SystemThreading_SpinLockDebugView
35 public int? OwnerThreadID
41 return m_spinLock.m_owner;
49 public SystemThreading_SpinLockDebugView(
SpinLock spinLock)
51 m_spinLock = spinLock;
55 private volatile int m_owner;
57 private const int SPINNING_FACTOR = 100;
59 private const int SLEEP_ONE_FREQUENCY = 40;
61 private const int SLEEP_ZERO_FREQUENCY = 10;
63 private const int TIMEOUT_CHECK_FREQUENCY = 10;
65 private const int LOCK_ID_DISABLE_MASK =
int.MinValue;
67 private const int LOCK_ANONYMOUS_OWNED = 1;
69 private const int WAITERS_MASK = 2147483646;
71 private const int ID_DISABLED_AND_ANONYMOUS_OWNED = -2147483647;
73 private const int LOCK_UNOWNED = 0;
75 private static int MAXIMUM_WAITERS = 2147483646;
79 [__DynamicallyInvokable]
82 [ReliabilityContract(
Consistency.WillNotCorruptState,
Cer.Success)]
83 [__DynamicallyInvokable]
90 return (m_owner & 1) != 0;
97 [__DynamicallyInvokable]
100 [ReliabilityContract(
Consistency.WillNotCorruptState,
Cer.Success)]
101 [__DynamicallyInvokable]
114 [__DynamicallyInvokable]
117 [ReliabilityContract(
Consistency.WillNotCorruptState,
Cer.Success)]
118 [__DynamicallyInvokable]
121 return (m_owner &
int.MinValue) == 0;
127 [__DynamicallyInvokable]
131 if (!enableThreadOwnerTracking)
133 m_owner |=
int.MinValue;
141 [__DynamicallyInvokable]
142 public void Enter(ref
bool lockTaken)
146 if (lockTaken || (owner & -2147483647) !=
int.MinValue ||
Interlocked.
CompareExchange(ref m_owner, owner | 1, owner, ref lockTaken) != owner)
148 ContinueTryEnter(-1, ref lockTaken);
156 [__DynamicallyInvokable]
169 [__DynamicallyInvokable]
173 if (num < -1 || num >
int.MaxValue)
187 [__DynamicallyInvokable]
188 public void TryEnter(
int millisecondsTimeout, ref
bool lockTaken)
192 if (((millisecondsTimeout < -1) | lockTaken) || (owner & -2147483647) !=
int.MinValue ||
Interlocked.
CompareExchange(ref m_owner, owner | 1, owner, ref lockTaken) != owner)
194 ContinueTryEnter(millisecondsTimeout, ref lockTaken);
198 private void ContinueTryEnter(
int millisecondsTimeout, ref
bool lockTaken)
206 if (millisecondsTimeout < -1)
211 if (millisecondsTimeout != -1 && millisecondsTimeout != 0)
213 startTime = TimeoutHelper.GetTime();
215 if (CdsSyncEtwBCLProvider.Log.IsEnabled())
217 CdsSyncEtwBCLProvider.Log.SpinLock_FastPathFailed(m_owner);
221 ContinueTryEnterWithThreadTracking(millisecondsTimeout, startTime, ref lockTaken);
224 int num =
int.MaxValue;
226 if ((owner & 1) == 0)
228 Thread.BeginCriticalRegion();
229 if (Interlocked.CompareExchange(ref m_owner, owner | 1, owner, ref lockTaken) == owner)
233 Thread.EndCriticalRegion();
235 else if ((owner & 0x7FFFFFFE) != MAXIMUM_WAITERS)
237 num = (Interlocked.Add(ref m_owner, 2) & 0x7FFFFFFE) >> 1;
239 if (millisecondsTimeout == 0 || (millisecondsTimeout != -1 && TimeoutHelper.UpdateTimeOut(startTime, millisecondsTimeout) <= 0))
244 int processorCount = PlatformHelper.ProcessorCount;
245 if (num < processorCount)
248 for (
int i = 1; i <= num * 100; i++)
250 Thread.SpinWait((num + i) * 100 * num2);
251 if (num2 < processorCount)
256 if ((owner & 1) == 0)
258 Thread.BeginCriticalRegion();
259 int value = ((owner & 0x7FFFFFFE) == 0) ? (owner | 1) : ((owner - 2) | 1);
260 if (Interlocked.CompareExchange(ref m_owner, value, owner, ref lockTaken) == owner)
264 Thread.EndCriticalRegion();
268 if (millisecondsTimeout != -1 && TimeoutHelper.UpdateTimeOut(startTime, millisecondsTimeout) <= 0)
277 if ((owner & 1) == 0)
279 Thread.BeginCriticalRegion();
280 int value2 = ((owner & 0x7FFFFFFE) == 0) ? (owner | 1) : ((owner - 2) | 1);
281 if (Interlocked.CompareExchange(ref m_owner, value2, owner, ref lockTaken) == owner)
285 Thread.EndCriticalRegion();
291 else if (num3 % 10 == 0)
299 if (num3 % 10 == 0 && millisecondsTimeout != -1 && TimeoutHelper.UpdateTimeOut(startTime, millisecondsTimeout) <= 0)
308 private void DecrementWaiters()
310 SpinWait spinWait =
default(SpinWait);
314 if ((owner & 0x7FFFFFFE) != 0 && Interlocked.CompareExchange(ref m_owner, owner - 2, owner) != owner)
323 private void ContinueTryEnterWithThreadTracking(
int millisecondsTimeout, uint startTime, ref
bool lockTaken)
326 int managedThreadId = Thread.CurrentThread.ManagedThreadId;
327 if (m_owner == managedThreadId)
329 throw new LockRecursionException(Environment.GetResourceString(
"SpinLock_TryEnter_LockRecursionException"));
331 SpinWait spinWait =
default(SpinWait);
337 Thread.BeginCriticalRegion();
338 if (Interlocked.CompareExchange(ref m_owner, managedThreadId, num, ref lockTaken) == num)
342 Thread.EndCriticalRegion();
344 switch (millisecondsTimeout)
351 if (spinWait.NextSpinWillYield && TimeoutHelper.UpdateTimeOut(startTime, millisecondsTimeout) <= 0)
360 [ReliabilityContract(
Consistency.WillNotCorruptState,
Cer.Success)]
361 [__DynamicallyInvokable]
364 if ((m_owner &
int.MinValue) == 0)
366 ExitSlowPath(useMemoryBarrier:
true);
378 [ReliabilityContract(
Consistency.WillNotCorruptState,
Cer.Success)]
379 [__DynamicallyInvokable]
380 public void Exit(
bool useMemoryBarrier)
382 if ((m_owner &
int.MinValue) != 0 && !useMemoryBarrier)
385 m_owner = (owner & -2);
389 ExitSlowPath(useMemoryBarrier);
394 private void ExitSlowPath(
bool useMemoryBarrier)
396 bool flag = (m_owner &
int.MinValue) == 0;
401 if (useMemoryBarrier)
405 Interlocked.Exchange(ref m_owner, 0);
409 Interlocked.Decrement(ref m_owner);
419 m_owner = (owner & -2);
static Thread CurrentThread
Gets the currently running thread.
void TryEnter(TimeSpan timeout, ref bool lockTaken)
Attempts to acquire the lock in a reliable manner, such that even if an exception occurs within the m...
Provides a mutual exclusion lock primitive where a thread trying to acquire the lock waits in a loop ...
The exception that is thrown when a method requires the caller to own the lock on a given Monitor,...
The exception that is thrown when the value of an argument is outside the allowable range of values a...
double TotalMilliseconds
Gets the value of the current T:System.TimeSpan structure expressed in whole and fractional milliseco...
bool IsHeldByCurrentThread
Gets whether the lock is held by the current thread.
Cer
Specifies a method's behavior when called within a constrained execution region.
SecurityAction
Specifies the security actions that can be performed using declarative security.
Provides information about, and means to manipulate, the current environment and platform....
static int CompareExchange(ref int location1, int value, int comparand)
Compares two 32-bit signed integers for equality and, if they are equal, replaces the first value.
void Exit()
Releases the lock.
bool IsThreadOwnerTrackingEnabled
Gets whether thread ownership tracking is enabled for this instance.
static void BeginCriticalRegion()
Notifies a host that execution is about to enter a region of code in which the effects of a thread ab...
static void EndCriticalRegion()
Notifies a host that execution is about to enter a region of code in which the effects of a thread ab...
The exception that is thrown when one of the arguments provided to a method is not valid.
SpinLock(bool enableThreadOwnerTracking)
Initializes a new instance of the T:System.Threading.SpinLock structure with the option to track thre...
int ManagedThreadId
Gets a unique identifier for the current managed thread.
Represents a time interval.To browse the .NET Framework source code for this type,...
The exception that is thrown when a method call is invalid for the object's current state.
void Enter(ref bool lockTaken)
Acquires the lock in a reliable manner, such that even if an exception occurs within the method call,...
Consistency
Specifies a reliability contract.
void Exit(bool useMemoryBarrier)
Releases the lock.
static int Decrement(ref int location)
Decrements a specified variable and stores the result, as an atomic operation.
void TryEnter(int millisecondsTimeout, ref bool lockTaken)
Attempts to acquire the lock in a reliable manner, such that even if an exception occurs within the m...
void TryEnter(ref bool lockTaken)
Attempts to acquire the lock in a reliable manner, such that even if an exception occurs within the m...
Provides atomic operations for variables that are shared by multiple threads.
bool IsHeld
Gets whether the lock is currently held by any thread.
Creates and controls a thread, sets its priority, and gets its status.