Exemple #1
0
        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);
        }
Exemple #2
0
        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);
        }
Exemple #3
0
            public void EnterWriteLock()
            {
                SpinWait sw = new SpinWait();

                do
                {
                    int state = rwlock;
                    if (state < RwWrite)
                    {
                        if (Interlocked.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 && Interlocked.CompareExchange(ref rwlock, state | RwWait, state) != state)
                    {
                        state = rwlock;
                    }
                    // Before falling to sleep
                    while (rwlock > RwWait)
                    {
                        sw.SpinOnce();
                    }
                } while (true);
            }
Exemple #4
0
        Node ListSearch(ulong key, TKey subKey, ref Node left, Node h)
        {
            Node leftNodeNext = null, rightNode = null;

            do
            {
                Node t     = h;
                Node tNext = t.Next;
                do
                {
                    if (!tNext.Marked)
                    {
                        left         = t;
                        leftNodeNext = tNext;
                    }
                    t = tNext.Marked ? tNext.Next : tNext;
                    if (t == tail)
                    {
                        break;
                    }

                    tNext = t.Next;
                } while (tNext.Marked || t.Key < key || (tNext.Key == key && !comparer.Equals(subKey, t.SubKey)));

                rightNode = t;

                if (leftNodeNext == rightNode)
                {
                    if (rightNode != tail && rightNode.Next.Marked)
                    {
                        continue;
                    }
                    else
                    {
                        return(rightNode);
                    }
                }

                if (Interlocked.CompareExchange(ref left.Next, rightNode, leftNodeNext) == leftNodeNext)
                {
                    if (rightNode != tail && rightNode.Next.Marked)
                    {
                        continue;
                    }
                    else
                    {
                        return(rightNode);
                    }
                }
            } while (true);
        }
Exemple #5
0
        Node SetBucket(uint index, Node node)
        {
            try
            {
                slim.EnterReadLock();
                CheckSegment(index, true);

                Interlocked.CompareExchange(ref buckets[index], node, null);
                return(buckets[index]);
            }
            finally
            {
                slim.ExitReadLock();
            }
        }
Exemple #6
0
        public bool Delete(uint key, TKey subKey, out T data)
        {
            uint b = key % (uint)size;
            Node bucket;

            if ((bucket = GetBucket(b)) == null)
            {
                bucket = InitializeBucket(b);
            }

            if (!ListDelete(bucket, ComputeRegularKey(key), subKey, out data))
            {
                return(false);
            }

            Interlocked.Decrement(ref count);
            return(true);
        }
Exemple #7
0
            public void EnterReadLock()
            {
                SpinWait sw = new SpinWait();

                do
                {
                    while ((rwlock & (RwWrite | RwWait)) > 0)
                    {
                        sw.SpinOnce();
                    }

                    if ((Interlocked.Add(ref rwlock, RwRead) & (RwWait | RwWait)) == 0)
                    {
                        return;
                    }

                    Interlocked.Add(ref rwlock, -RwRead);
                } while (true);
            }
Exemple #8
0
        bool ListDelete(Node startPoint, ulong key, TKey subKey, out T data)
        {
            Node rightNode = null, rightNodeNext = null, leftNode = null;

            data = default(T);
            Node markedNode = null;

            do
            {
                rightNode = ListSearch(key, subKey, ref leftNode, startPoint);
                if (rightNode == tail || rightNode.Key != key || !comparer.Equals(subKey, rightNode.SubKey))
                {
                    return(false);
                }

                data          = rightNode.Data;
                rightNodeNext = rightNode.Next;

                if (!rightNodeNext.Marked)
                {
                    if (markedNode == null)
                    {
                        markedNode = new Node();
                    }
                    markedNode.Init(rightNodeNext);

                    if (Interlocked.CompareExchange(ref rightNode.Next, markedNode, rightNodeNext) == rightNodeNext)
                    {
                        break;
                    }
                }
            } while (true);

            if (Interlocked.CompareExchange(ref leftNode.Next, rightNodeNext, rightNode) != rightNode)
            {
                ListSearch(rightNode.Key, subKey, ref leftNode, startPoint);
            }

            return(true);
        }
Exemple #9
0
        public bool TryDequeue(out T result)
        {
            result = default(T);
            bool advanced = false;

            while (!advanced)
            {
                Node oldHead = head;
                Node oldTail = tail;
                Node oldNext = oldHead.Next;

                if (oldHead == head)
                {
                    // Empty case ?
                    if (oldHead == oldTail)
                    {
                        // This should be false then
                        if (oldNext != null)
                        {
                            // If not then the linked list is mal formed, update tail
                            Interlocked.CompareExchange(ref tail, oldNext, oldTail);
                            continue;
                        }
                        result = default(T);
                        return(false);
                    }
                    else
                    {
                        result   = oldNext.Value;
                        advanced = Interlocked.CompareExchange(ref head, oldNext, oldHead) == oldHead;
                    }
                }
            }

            Interlocked.Decrement(ref count);

            return(true);
        }
Exemple #10
0
        bool ListInsert(Node newNode, Node startPoint, out Node current, Func <T> dataCreator)
        {
            ulong key = newNode.Key;
            Node  rightNode = null, leftNode = null;

            do
            {
                rightNode = current = ListSearch(key, newNode.SubKey, ref leftNode, startPoint);
                if (rightNode != tail && rightNode.Key == key && comparer.Equals(newNode.SubKey, rightNode.SubKey))
                {
                    return(false);
                }

                newNode.Next = rightNode;
                if (dataCreator != null)
                {
                    newNode.Data = dataCreator();
                }
                if (Interlocked.CompareExchange(ref leftNode.Next, newNode, rightNode) == rightNode)
                {
                    return(true);
                }
            } while (true);
        }
Exemple #11
0
 public void ExitWriteLock()
 {
     Interlocked.Add(ref rwlock, -RwWrite);
 }
Exemple #12
0
 public void ExitReadLock()
 {
     Interlocked.Add(ref rwlock, -RwRead);
 }