public PopResult PopBottom(out T obj) { obj = default(T); int b = CustomInterlocked.Decrement(ref bottom); var a = array; int t = top; int size = b - t; if (size < 0) { // Set bottom to t CustomInterlocked.Add(ref bottom, t - b); return(PopResult.Empty); } obj = a.segment[b % a.size]; if (size > 0) { return(PopResult.Succeed); } CustomInterlocked.Add(ref bottom, t + 1 - b); if (CustomInterlocked.CompareExchange(ref top, t + 1, t) != t) { return(PopResult.Empty); } return(PopResult.Succeed); }
public void PushRange(T[] items, int startIndex, int count) { RangeArgumentsCheck(items, startIndex, count); Node insert = null; Node first = null; for (int i = startIndex; i < count; i++) { Node temp = new Node(); temp.Value = items[i]; temp.Next = insert; insert = temp; if (first == null) { first = temp; } } do { first.Next = Head; } while (CustomInterlocked.CompareExchange(ref head, insert, first.Next) != first.Next); CustomInterlocked.Add(ref this.count, count); }
public void EnterReadLock() { SpinWait sw = new SpinWait(); do { while ((rwlock & (RwWrite | RwWait)) > 0) { sw.SpinOnce(); } if ((CustomInterlocked.Add(ref rwlock, RwRead) & (RwWait | RwWait)) == 0) { return; } CustomInterlocked.Add(ref rwlock, -RwRead); } while (true); }
public int TryPopRange(T[] items, int startIndex, int count) { RangeArgumentsCheck(items, startIndex, count); Node temp; Node end; do { temp = Head; if (temp == null) { return(0); } end = temp; for (int j = 0; j < count; j++) { end = end.Next; if (end == null) { break; } } } while (CustomInterlocked.CompareExchange(ref head, end, temp) != temp); int i; for (i = startIndex; i < startIndex + count && temp != null; i++) { items[i] = temp.Value; end = temp; temp = temp.Next; } CustomInterlocked.Add(ref this.count, -(i - startIndex)); return(i - startIndex); }
public void ExitWriteLock() { CustomInterlocked.Add(ref rwlock, -RwWrite); }
public void ExitReadLock() { CustomInterlocked.Add(ref rwlock, -RwRead); }