public void Enqueue(T item) { Node node = new Node(); node.Value = item; Node oldTail = null; Node oldNext = null; bool update = false; while (!update) { oldTail = tail; oldNext = oldTail.Next; // Did tail was already updated ? if (tail == oldTail) { if (oldNext == null) { // The place is for us update = Interlocked.CompareExchange(ref tail.Next, node, null) == null; } else { // another Thread already used the place so give him a hand by putting tail where it should be Interlocked.CompareExchange(ref tail, oldNext, oldTail); } } } // At this point we added correctly our node, now we have to update tail. If it fails then it will be done by another thread Interlocked.CompareExchange(ref tail, node, oldTail); Interlocked.Increment(ref count); }
bool InsertInternal(uint key, TKey subKey, T data, Func <T> dataCreator, out Node current) { Node node = new Node().Init(ComputeRegularKey(key), subKey, data); uint b = key % (uint)size; Node bucket; if ((bucket = GetBucket(b)) == null) { bucket = InitializeBucket(b); } if (!ListInsert(node, bucket, out current, dataCreator)) { return(false); } int csize = size; if (Interlocked.Increment(ref count) / csize > MaxLoad && (csize & 0x40000000) == 0) { Interlocked.CompareExchange(ref size, 2 * csize, csize); } current = node; return(true); }