public int Users;
}
- // Implement the ticket SpinLock algorithm described on http://locklessinc.com/articles/locks/
- // This lock is usable on both endianness
- // TODO: some 32 bits platform apparently doesn't support CAS with 64 bits value
+ /* Implement the ticket SpinLock algorithm described on http://locklessinc.com/articles/locks/
+ * This lock is usable on both endianness.
+ * All the try/finally patterns in this class and various extra gimmicks compared to the original
+ * algorithm are here to avoid problems caused by asynchronous exceptions.
+ */
[System.Diagnostics.DebuggerDisplay ("IsHeld = {IsHeld}")]
[System.Diagnostics.DebuggerTypeProxy ("System.Threading.SpinLock+SystemThreading_SpinLockDebugView")]
public struct SpinLock
while (slot != ticket.Value) {
wait.SpinOnce ();
- if (stallTickets != null && stallTickets.TryRemove (ticket.Value))
+ while (stallTickets != null && stallTickets.TryRemove (ticket.Value))
++ticket.Value;
}
} finally {
bool stop = false;
do {
- if (stallTickets != null && stallTickets.TryRemove (ticket.Value))
+ while (stallTickets != null && stallTickets.TryRemove (ticket.Value))
++ticket.Value;
long u = ticket.Users;
} while (!stop && (millisecondsTimeout == -1 || (sw.ElapsedMilliseconds - start) < millisecondsTimeout));
}
+ [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
public void Exit ()
{
Exit (false);
throw new SynchronizationLockException ("Current thread is not the owner of this lock");
threadWhoTookLock = int.MinValue;
- // Fast path
do {
if (useMemoryBarrier)
Interlocked.Increment (ref ticket.Value);