using System.Threading; //from unify wiki namespace Svelto.DataStructures { public class SingleLinkEntityView { // Note; the Next member cannot be a property since // it participates in many CAS operations public SingleLinkEntityView Next; public T Item; } public static class SyncMethods { public static bool CAS(ref T location, T comparand, T newValue) where T : class { return (object)comparand == (object)Interlocked.CompareExchange(ref location, newValue, comparand); } } public class LockFreeLinkPool { private SingleLinkEntityView head; public LockFreeLinkPool() { head = new SingleLinkEntityView(); } public void Push(SingleLinkEntityView newEntityView) { newEntityView.Item = default(T); do { newEntityView.Next = head.Next; } while (!SyncMethods.CAS>(ref head.Next, newEntityView.Next, newEntityView)); return; } public bool Pop(out SingleLinkEntityView entityView) { do { entityView = head.Next; if (entityView == null) { return false; } } while (!SyncMethods.CAS>(ref head.Next, entityView, entityView.Next)); return true; } } public class LockFreeQueue { SingleLinkEntityView head; SingleLinkEntityView tail; LockFreeLinkPool trash; public LockFreeQueue() { head = new SingleLinkEntityView(); tail = head; trash = new LockFreeLinkPool(); } public void Enqueue(T item) { SingleLinkEntityView oldTail = null; SingleLinkEntityView oldTailNext; SingleLinkEntityView newEntityView; if (!trash.Pop(out newEntityView)) { newEntityView = new SingleLinkEntityView(); } else { newEntityView.Next = null; } newEntityView.Item = item; bool newEntityViewWasAdded = false; while (!newEntityViewWasAdded) { oldTail = tail; oldTailNext = oldTail.Next; if (tail == oldTail) { if (oldTailNext == null) newEntityViewWasAdded = SyncMethods.CAS>(ref tail.Next, null, newEntityView); else SyncMethods.CAS>(ref tail, oldTail, oldTailNext); } } SyncMethods.CAS>(ref tail, oldTail, newEntityView); } public bool Dequeue(out T item) { item = default(T); SingleLinkEntityView oldHead = null; bool haveAdvancedHead = false; while (!haveAdvancedHead) { oldHead = head; SingleLinkEntityView oldTail = tail; SingleLinkEntityView oldHeadNext = oldHead.Next; if (oldHead == head) { if (oldHead == oldTail) { if (oldHeadNext == null) { return false; } SyncMethods.CAS>(ref tail, oldTail, oldHeadNext); } else { item = oldHeadNext.Item; haveAdvancedHead = SyncMethods.CAS>(ref head, oldHead, oldHeadNext); if (haveAdvancedHead) { trash.Push(oldHead); } } } } return true; } } }