public void EnterWriteLock() { ClientSpinWait sw = new ClientSpinWait(); do { int state = rwlock; if (state < RwWrite) { if (ClientInterlocked.CompareExchange(ref rwlock, RwWrite, state) == state) { return; } state = rwlock; } // We register our interest in taking the Write lock (if upgradeable it's already done) while ((state & RwWait) == 0 && ClientInterlocked.CompareExchange(ref rwlock, state | RwWait, state) != state) { state = rwlock; } // Before falling to sleep while (rwlock > RwWait) { sw.SpinOnce(); } } while (true); }
public void Enter(ref bool lockTaken) { if (lockTaken) { throw new ArgumentException("lockTaken", "lockTaken must be initialized to false"); } if (isThreadOwnerTrackingEnabled && IsHeldByCurrentThread) { throw new LockRecursionException(); } int slot = -1; RuntimeHelpers.PrepareConstrainedRegions(); try { slot = ClientInterlocked.Increment(ref ticket.Users) - 1; ClientSpinWait wait = new ClientSpinWait(); while (slot != ticket.Value) { wait.SpinOnce(); while (stallTickets != null && ((ClientConcurrentOrderedList <int>)stallTickets).TryRemove(ticket.Value)) { ++ticket.Value; } } } finally { if (slot == ticket.Value) { lockTaken = true; threadWhoTookLock = Thread.CurrentThread.ManagedThreadId; } else if (slot != -1) { // We have been interrupted, initialize stallTickets if (stallTickets == null) { ClientInterlocked.CompareExchange(ref stallTickets, new ClientConcurrentOrderedList <int>(), null); } ((ClientConcurrentOrderedList <int>)stallTickets).TryAdd(slot); } } }
public void TryEnter(int millisecondsTimeout, ref bool lockTaken) { if (millisecondsTimeout < -1) { throw new ArgumentOutOfRangeException("milliSeconds", "millisecondsTimeout is a negative number other than -1"); } if (lockTaken) { throw new ArgumentException("lockTaken", "lockTaken must be initialized to false"); } if (isThreadOwnerTrackingEnabled && IsHeldByCurrentThread) { throw new LockRecursionException(); } long start = millisecondsTimeout == -1 ? 0 : sw.ElapsedMilliseconds; bool stop = false; do { while (stallTickets != null && ((ClientConcurrentOrderedList <int>)stallTickets).TryRemove(ticket.Value)) { ++ticket.Value; } long u = ticket.Users; long totalValue = (u << 32) | u; long newTotalValue = BitConverter.IsLittleEndian ? (u << 32) | (u + 1) : ((u + 1) << 32) | u; RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { lockTaken = ClientInterlocked.CompareExchange(ref ticket.TotalValue, newTotalValue, totalValue) == totalValue; if (lockTaken) { threadWhoTookLock = Thread.CurrentThread.ManagedThreadId; stop = true; } } } while (!stop && (millisecondsTimeout == -1 || (sw.ElapsedMilliseconds - start) < millisecondsTimeout)); }