Exemplo n.º 1
0
            public void EnterWriteLock()
            {
                SpinWait sw = new SpinWait();

                do
                {
                    int state = rwlock;
                    if (state < RwWrite)
                    {
                        if (CustomInterlocked.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 && CustomInterlocked.CompareExchange(ref rwlock, state | RwWait, state) != state)
                    {
                        state = rwlock;
                    }
                    // Before falling to sleep
                    while (rwlock > RwWait)
                    {
                        sw.SpinOnce();
                    }
                } while (true);
            }
Exemplo n.º 2
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 = CustomInterlocked.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
                        CustomInterlocked.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
            CustomInterlocked.CompareExchange(ref tail, node, oldTail);
            CustomInterlocked.Increment(ref count);
        }
Exemplo n.º 3
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 (CustomInterlocked.Increment(ref count) / csize > MaxLoad && (csize & 0x40000000) == 0)
            {
                CustomInterlocked.CompareExchange(ref size, 2 * csize, csize);
            }

            current = node;

            return(true);
        }
        bool ListPop(out T data)
        {
            Node rightNode = null, rightNodeNext = null, leftNode = head;

            data = default(T);

            do
            {
                rightNode = head.Next;
                if (rightNode == tail)
                {
                    return(false);
                }

                data = rightNode.Data;

                rightNodeNext = rightNode.Next;
                if (!rightNodeNext.Marked)
                {
                    if (CustomInterlocked.CompareExchange(ref rightNode.next, new Node(rightNodeNext), rightNodeNext) == rightNodeNext)
                    {
                        break;
                    }
                }
            } while (true);

            if (CustomInterlocked.CompareExchange(ref leftNode.next, rightNodeNext, rightNode) != rightNodeNext)
            {
                ListSearch(rightNode.Key, ref leftNode);
            }

            return(true);
        }
Exemplo n.º 5
0
        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);
        }
Exemplo n.º 6
0
        public bool CompareAndExchange(bool expected, bool newVal)
        {
            int newTemp      = newVal ? Set : UnSet;
            int expectedTemp = expected ? Set : UnSet;

            return(CustomInterlocked.CompareExchange(ref flag, newTemp, expectedTemp) == expectedTemp);
        }
Exemplo n.º 7
0
        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 bool TryRemoveHash(int key, out T data)
        {
            if (ListDelete(key, out data))
            {
                CustomInterlocked.Decrement(ref count);
                return(true);
            }

            return(false);
        }
Exemplo n.º 9
0
        public void Add(T item)
        {
            int             index;
            CyclicDeque <T> bag = GetBag(out index);

            bag.PushBottom(item);
            staging.TryAdd(index, bag);
            AddHint(index);
            CustomInterlocked.Increment(ref count);
        }
Exemplo n.º 10
0
        public bool TryGetNextCompletion(out TCompletion continuation)
        {
            continuation = null;

            if (single != null && (continuation = (TCompletion)CustomInterlocked.Exchange(ref single, null)) != null)
            {
                return(true);
            }

            return(completed != null && Completed.TryPop(out continuation));
        }
Exemplo n.º 11
0
        public void Push(T item)
        {
            Node temp = new Node();

            temp.Value = item;
            do
            {
                temp.Next = Head;
            } while (CustomInterlocked.CompareExchange(ref head, temp, temp.Next) != temp.Next);

            CustomInterlocked.Increment(ref count);
        }
Exemplo n.º 12
0
 public void Add(TCompletion continuation)
 {
     if (single == null && CustomInterlocked.CompareExchange(ref single, continuation, null) == null)
     {
         return;
     }
     if (completed == null)
     {
         CustomInterlocked.CompareExchange(ref completed, new ConcurrentOrderedList <TCompletion> (), null);
     }
     Completed.TryAdd(continuation);
 }
Exemplo n.º 13
0
        void AddHint(int index)
        {
            // We only take thread index that can be stored in 5 bits (i.e. thread ids 1-15)
            if (index > 0xF)
            {
                return;
            }
            var hs = hints;

            // If cas failed then we don't retry
            CustomInterlocked.CompareExchange(ref hints, (int)(((uint)hs) << 4 | (uint)index), (int)hs);
        }
Exemplo n.º 14
0
        Node SetBucket(uint index, Node node)
        {
            try {
                slim.EnterReadLock();
                CheckSegment(index, true);

                CustomInterlocked.CompareExchange(ref buckets[index], node, null);
                return((Node)buckets[index]);
            } finally {
                slim.ExitReadLock();
            }
        }
Exemplo n.º 15
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 (CustomInterlocked.CompareExchange(ref left.next, rightNode, leftNodeNext) == leftNodeNext)
                {
                    if (rightNode != tail && rightNode.Next.Marked)
                    {
                        continue;
                    }
                    else
                    {
                        return(rightNode);
                    }
                }
            } while (true);
        }
        Node ListSearch(int key, ref Node left)
        {
            Node leftNodeNext = null, rightNode = null;

            do
            {
                Node t     = head;
                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);

                rightNode = t;

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

                if (CustomInterlocked.CompareExchange(ref left.next, rightNode, leftNodeNext) == leftNodeNext)
                {
                    if (rightNode != tail && rightNode.Next.Marked)
                    {
                        continue;
                    }
                    else
                    {
                        return(rightNode);
                    }
                }
            } while (true);
        }
Exemplo n.º 17
0
        public bool TryTake(out T result)
        {
            result = default(T);

            if (count == 0)
            {
                return(false);
            }

            int             hintIndex;
            CyclicDeque <T> bag = GetBag(out hintIndex, false);
            bool            ret = true;

            if (bag == null || bag.PopBottom(out result) != PopResult.Succeed)
            {
                var self = bag;
                ret = false;
                foreach (var other in staging)
                {
                    // Try to retrieve something based on a hint
                    ret = TryGetHint(out hintIndex) && (bag = container[hintIndex]).PopTop(out result) == PopResult.Succeed;

                    // We fall back to testing our slot
                    if (!ret && other.Value != self)
                    {
                        var status = other.Value.PopTop(out result);
                        while (status == PopResult.Abort)
                        {
                            status = other.Value.PopTop(out result);
                        }
                        ret       = status == PopResult.Succeed;
                        hintIndex = other.Key;
                        bag       = other.Value;
                    }

                    // If we found something, stop
                    if (ret)
                    {
                        break;
                    }
                }
            }

            if (ret)
            {
                TidyBag(hintIndex, bag);
                CustomInterlocked.Decrement(ref count);
            }

            return(ret);
        }
Exemplo n.º 18
0
        public bool Remove(TCompletion continuation)
        {
            TCompletion temp = Single;

            if (temp != null && temp == continuation && CustomInterlocked.CompareExchange(ref single, null, continuation) == continuation)
            {
                return(true);
            }
            if (completed != null)
            {
                return(Completed.TryRemove(continuation));
            }
            return(false);
        }
        public bool TryAdd(T data)
        {
            Node node = new Node();

            node.Data = data;
            node.Key  = comparer.GetHashCode(data);

            if (ListInsert(node))
            {
                CustomInterlocked.Increment(ref count);
                return(true);
            }

            return(false);
        }
Exemplo n.º 20
0
        public bool PeekBottom(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)
            {
                return(false);
            }

            obj = a.segment[b % a.size];
            return(true);
        }
Exemplo n.º 21
0
        bool TryGetHint(out int index)
        {
            /* Funny little thing to know, since hints is signed (because CAS has no uint overload),
             * a shift-right operation is an arithmetic shift which might set high-order right bits
             * to 1 instead of 0 if the number turns negative.
             */
            var hs = hints;

            index = 0;

            if (CustomInterlocked.CompareExchange(ref hints, (int)(((uint)hs) >> 4), hs) == hs)
            {
                index = (int)(hs & 0xF);
            }

            return(index > 0);
        }
Exemplo n.º 22
0
        public void Execute()
        {
            if (CustomInterlocked.Decrement(ref counter) != 0)
            {
                return;
            }

            owner.Status = TaskStatus.Running;

            bool             canceled   = false;
            List <Exception> exceptions = null;

            foreach (var task in tasks)
            {
                if (task.IsFaulted)
                {
                    if (exceptions == null)
                    {
                        exceptions = new List <Exception> ();
                    }

                    exceptions.AddRange(task.Exception.InnerExceptions);
                    continue;
                }

                if (task.IsCanceled)
                {
                    canceled = true;
                }
            }

            if (exceptions != null)
            {
                owner.TrySetException(new AggregateException(exceptions), false, false);
                return;
            }

            if (canceled)
            {
                owner.CancelReal();
                return;
            }

            owner.Finish();
        }
Exemplo n.º 23
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);
            }

            CustomInterlocked.Decrement(ref count);
            return(true);
        }
Exemplo n.º 24
0
        public override IList <IEnumerator <KeyValuePair <long, Tuple <long, long> > > > GetOrderablePartitions(int partitionCount)
        {
            if (partitionCount <= 0)
            {
                throw new ArgumentOutOfRangeException("partitionCount");
            }

            long        currentIndex = 0;
            Func <long> getNextIndex = () => CustomInterlocked.Increment(ref currentIndex) - 1;

            var enumerators = new IEnumerator <KeyValuePair <long, Tuple <long, long> > > [partitionCount];

            for (int i = 0; i < partitionCount; i++)
            {
                enumerators[i] = GetEnumerator(getNextIndex);
            }

            return(enumerators);
        }
Exemplo n.º 25
0
        public void PushBottom(T obj)
        {
            int b = bottom;
            var a = array;

            // Take care of growing
            var size = b - top - upperBound;

            if (size > a.Size)
            {
                upperBound = top;
                a          = a.Grow(b, upperBound);
                array      = a;
            }

            // Register the new value
            a.segment[b % a.size] = obj;
            CustomInterlocked.Increment(ref bottom);
        }
Exemplo n.º 26
0
            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);
            }
        bool ListInsert(Node newNode)
        {
            int  key = newNode.Key;
            Node rightNode = null, leftNode = null;

            do
            {
                rightNode = ListSearch(key, ref leftNode);
                if (rightNode != tail && rightNode.Key == key)
                {
                    return(false);
                }

                newNode.next = rightNode;
                if (CustomInterlocked.CompareExchange(ref leftNode.next, newNode, rightNode) == rightNode)
                {
                    return(true);
                }
            } while (true);
        }
Exemplo n.º 28
0
        public bool TryDequeue(out T result)
        {
            result = default(T);
            Node oldNext  = null;
            bool advanced = false;

            while (!advanced)
            {
                Node oldHead = Head;
                Node oldTail = Tail;
                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
                            CustomInterlocked.CompareExchange(ref tail, oldNext, oldTail);
                            continue;
                        }
                        result = default(T);
                        return(false);
                    }
                    else
                    {
                        result   = oldNext.Value;
                        advanced = CustomInterlocked.CompareExchange(ref head, oldNext, oldHead) == oldHead;
                    }
                }
            }

            oldNext.Value = default(T);

            CustomInterlocked.Decrement(ref count);

            return(true);
        }
Exemplo n.º 29
0
        public bool TryPop(out T result)
        {
            Node temp;

            do
            {
                temp = Head;
                // The stak is empty
                if (temp == null)
                {
                    result = default(T);
                    return(false);
                }
            } while (CustomInterlocked.CompareExchange(ref head, temp.Next, temp) != temp);

            CustomInterlocked.Decrement(ref count);

            result = temp.Value;

            return(true);
        }
Exemplo n.º 30
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 (CustomInterlocked.CompareExchange(ref rightNode.next, markedNode, rightNodeNext) == rightNodeNext)
                    {
                        break;
                    }
                }
            } while (true);

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

            return(true);
        }