Example #1
0
        private void Add(T value, ISingleLinkNode <T> previous)
        {
            //Let's create the node first
            var node = new SingleLinkNode <T>(value);

            //Now, we check if the list is empty, and if it is, then we add the node in the first place
            if (FirstNode == null)
            {
                FirstNode      = node;
                FirstNode.Next = node;
                //All done
                return;
            }
            if (previous == LastNode || previous == null)
            {
                //wether the previous is null or last, it's always going to set the first node
                LastNode.Next = node;
                node.Next     = FirstNode;
                if (previous == null)
                {
                    FirstNode = node;
                }
                return;
            }
            var b = previous.Next;

            previous.Next = node;
            node.Next     = b;
        }
Example #2
0
    public T Dequeue()
    {
        T    result           = default(T);
        bool HaveAdvancedHead = false;

        while (!HaveAdvancedHead)
        {
            SingleLinkNode <T> oldHead     = head;
            SingleLinkNode <T> oldTail     = tail;
            SingleLinkNode <T> oldHeadNext = oldHead.Next;

            if (oldHead == head)
            {
                if (oldHead == oldTail)
                {
                    if (oldHeadNext == null)
                    {
                        return(default(T));
                    }

                    CAS(ref tail, oldTail, oldHeadNext);
                }
                else
                {
                    result           = oldHeadNext.Item;
                    HaveAdvancedHead = CAS(ref head, oldHead, oldHeadNext);
                }
            }
        }

        Interlocked.Decrement(ref count);
        return(result);
    }
        // Can be called from another thread
        private void getBTDataFromThread(string data)
        {
            SingleLinkNode <string> node = new SingleLinkNode <string>();

            node.Item = data;
            BTDataIn.Push(node);
        }
Example #4
0
        public override bool Pop(out T pItem)
        {
            pItem = default(T);
            SingleLinkNode oldHead = null;

            bool haveAdvancedHead = false;

            while (!haveAdvancedHead)
            {
                oldHead = mHead;
                SingleLinkNode oldTail     = mTail;
                SingleLinkNode oldHeadNext = oldHead.Next;

                if (oldHead == mHead)
                {
                    if (oldHead == oldTail)
                    {
                        if (oldHeadNext == null)
                        {
                            return(false);
                        }
                        CompareAndExchange(ref mTail, oldTail, oldHeadNext);
                    }

                    else
                    {
                        pItem            = oldHeadNext.Item;
                        haveAdvancedHead =
                            CompareAndExchange(ref mHead, oldHead, oldHeadNext);
                    }
                }
            }
            Interlocked.Decrement(ref Count);
            return(true);
        }
Example #5
0
        private void Add(T value, ISingleLinkNode <T> previous)
        {
            //Let's create the node first
            var node = new SingleLinkNode <T>(value);

            //Now, we check if the list is empty, and if it is, then we add the node in the first place
            if (FirstNode == null)
            {
                FirstNode = node;
                //All done
                return;
            }

            //Let's check if this element goes to the head node (special case)
            if (previous == null)
            {
                node.Next = FirstNode;
                FirstNode = node;
                return;
            }

            //Next, we set "previous"'s Next as the node's next
            node.Next = previous.Next;

            //Now, all we need is to set the "previous"'s Next as the node
            previous.Next = node;

            //Presto finito!
        }
Example #6
0
        // Can be called from another thread
        private void getBTDataFromThread(byte[] data)
        {
            SingleLinkNode <byte[]> node = new SingleLinkNode <byte[]>();

            node.Item = data;
            BTDataIn.Push(node);
        }
Example #7
0
    public void Enqueue(T item)
    {
        SingleLinkNode <T> oldTail = null;
        SingleLinkNode <T> oldNext = null;

        SingleLinkNode <T> node = new SingleLinkNode <T>(item);

        /* 循环直到更新tail的next指向我们新的node节点 */
        bool UpdatedNewLink = false;

        while (!UpdatedNewLink)
        {
            /* 保留tail和他的next一分本地拷贝,避免其他线程改动tail */
            oldTail = tail;
            oldNext = oldTail.Next; /*必须用oldTail,本地拷贝, 因为tail可能被其他线程改动了*/

            if (tail == oldTail)
            {
                if (oldNext == null && CAS(ref tail.Next, null, node))
                {
                    //tail.next = node
                    Interlocked.Increment(ref count);
                    UpdatedNewLink = true;
                }
                else
                {
                    /*tail = tail.next*/
                    CAS(ref tail, oldTail, oldNext);
                }
            }
        }

        /* tail = node*/
        CAS(ref tail, oldTail, node);
    }
Example #8
0
        public bool Shift(out T pItem)
        {
            pItem = default(T);
            if (mHead == null)
            {
                return(false);
            }
            SingleLinkNode oldHead = null;

            bool haveAdvancedHead = false;

            while (!haveAdvancedHead)
            {
                oldHead = mHead;
                if (oldHead != null)
                {
                    SingleLinkNode oldHeadNext = oldHead.Next;
                    if (CompareAndExchange(ref mHead, oldHead, oldHeadNext))
                    {
                        pItem = oldHead.Item;
                        return(true);
                    }
                }
            }
            return(false);
        }
Example #9
0
        public bool Dequeue(out T pItem)
        {
            pItem = default(T);
            SingleLinkNode oldHead = null;

            bool haveAdvancedHead = false;

            while (!haveAdvancedHead)
            {
                oldHead = mHead;
                SingleLinkNode oldTail     = mTail;
                SingleLinkNode oldHeadNext = oldHead.Next;

                if (oldHead == mHead)
                {
                    if (oldHead == oldTail)
                    {
                        if (oldHeadNext == null)
                        {
                            return(false);
                        }
                        CompareAndExchange(ref mTail, oldTail, oldHeadNext);
                    }

                    else
                    {
                        pItem            = oldHeadNext.Item;
                        haveAdvancedHead =
                            CompareAndExchange(ref mHead, oldHead, oldHeadNext);
                    }
                }
            }
            return(true);
        }
Example #10
0
        public override void Push(T pItem)
        {
            SingleLinkNode oldTail = null;
            SingleLinkNode oldTailNext;

            SingleLinkNode newNode = new SingleLinkNode();

            newNode.Item = pItem;

            bool newNodeWasAdded = false;

            while (!newNodeWasAdded)
            {
                oldTail     = mTail;
                oldTailNext = oldTail.Next;

                if (mTail == oldTail)
                {
                    if (oldTailNext == null)
                    {
                        newNodeWasAdded = CompareAndExchange(ref mTail.Next, null, newNode);
                    }
                    else
                    {
                        CompareAndExchange(ref mTail, oldTail, oldTailNext);
                    }
                }
            }

            CompareAndExchange(ref mTail, oldTail, newNode);
            Interlocked.Increment(ref Count);
        }
Example #11
0
        public void Enqueue(T pItem)
        {
            SingleLinkNode oldTail = null;
            SingleLinkNode oldTailNext;

            SingleLinkNode newNode = new SingleLinkNode();

            newNode.Item = pItem;

            bool newNodeWasAdded = false;

            while (!newNodeWasAdded)
            {
                oldTail     = mTail;
                oldTailNext = oldTail.Next;

                if (mTail == oldTail)
                {
                    if (oldTailNext == null)
                    {
                        newNodeWasAdded = CompareAndExchange(ref mTail.Next, null, newNode);
                    }
                    else
                    {
                        CompareAndExchange(ref mTail, oldTail, oldTailNext);
                    }
                }
            }
            CompareAndExchange(ref mTail, oldTail, newNode);
        }
Example #12
0
            public bool Dequeue(out T item)
            {
                item = default(T);
                SingleLinkNode <T> oldHead = null;

                bool haveAdvancedHead = false;

                while (!haveAdvancedHead)
                {
                    oldHead = head;
                    SingleLinkNode <T> oldTail     = tail;
                    SingleLinkNode <T> oldHeadNext = oldHead.Next;

                    if (oldHead == head)
                    {
                        if (oldHead == oldTail)
                        {
                            if (oldHeadNext == null)
                            {
                                return(false);
                            }
                            SyncMethods.CAS <SingleLinkNode <T> >(ref tail, oldTail, oldHeadNext);
                        }

                        else
                        {
                            item             = oldHeadNext.Item;
                            haveAdvancedHead =
                                SyncMethods.CAS <SingleLinkNode <T> >(ref head, oldHead, oldHeadNext);
                        }
                    }
                }
                return(true);
            }
Example #13
0
            public void Enqueue(T item)
            {
                SingleLinkNode <T> oldTail = null;
                SingleLinkNode <T> oldTailNext;

                SingleLinkNode <T> newNode = new SingleLinkNode <T>();

                newNode.Item = item;

                bool newNodeWasAdded = false;

                while (!newNodeWasAdded)
                {
                    oldTail     = tail;
                    oldTailNext = oldTail.Next;

                    if (tail == oldTail)
                    {
                        if (oldTailNext == null)
                        {
                            newNodeWasAdded = SyncMethods.CAS <SingleLinkNode <T> >(ref tail.Next, null, newNode);
                        }
                        else
                        {
                            SyncMethods.CAS <SingleLinkNode <T> >(ref tail, oldTail, oldTailNext);
                        }
                    }
                }

                SyncMethods.CAS <SingleLinkNode <T> >(ref tail, oldTail, newNode);
            }
        /// <summary>
        /// Enqueue an item
        /// </summary>
        /// <param name="item">Item to enqeue</param>
        public void Enqueue(T item)
        {
            SingleLinkNode newNode = new SingleLinkNode {
                Item = item
            };

            while (true)
            {
                SingleLinkNode oldTail     = tail;
                SingleLinkNode oldTailNext = oldTail.Next;

                if (tail == oldTail)
                {
                    if (oldTailNext != null)
                    {
                        CAS(ref tail, oldTail, oldTailNext);
                    }
                    else if (CAS(ref tail.Next, null, newNode))
                    {
                        CAS(ref tail, oldTail, newNode);
                        Interlocked.Increment(ref count);
                        return;
                    }
                }
            }
        }
Example #15
0
 public void Clear()
 {
     do
     {
         tail = head;
     }while (!CAS(ref head.Next, tail.Next, null));
 }
Example #16
0
 /// <summary>
 /// Create a new instance.
 /// </summary>
 /// <param name="capacity">Number of hash buckets to use for the name table.</param>
 public LockFreeXmlNameTable(int capacity)
 {
     if(capacity <= 0) {
         throw new ArgumentException("capacity must be positive number", "capacity");
     }
     _buckets = new SingleLinkNode<Entry>[capacity];
     _capacityIsPowerOf2 = ((capacity & (capacity - 1)) == 0);
 }
Example #17
0
        // Update is called once per frame
        void Update()
        {
            // Check Concurrent Pool for data
            SingleLinkNode <byte[]> node = null;

            int dataInSize = 0;

            while (dataIn.Pop(out node))
            {
                dataInSize++;

                byte[] data = node.Item;
                getDataDelegate(data);
                //Debug.Log("DataServerUpdate() got data");

                // parse the data byte array into float values
                dataHandler.parseIncomingBTByteArray(data);


                ////profile time spent
                //after = DateTime.Now;
                //duration = after.Subtract(before);
                //before = DateTime.Now;
                //average_last_ten += duration.Milliseconds;
                //average_last_hundred += duration.Milliseconds;
                //count++;
                //big_count++;


                //if (big_count >= 100)
                //{
                //    Debug.Log("average of last hundred " + average_last_hundred / big_count);
                //    big_count = 0;
                //    average_last_hundred = 0;
                //}

                //if (count >= 10)
                //{
                //    Debug.Log("average of last ten " + average_last_ten / count);
                //    count = 0;
                //    average_last_ten = 0;
                //}
            }

            //if(dataInSize > 0)
            //Debug.Log("size of data q " + dataInSize);


            if (Input.GetKeyDown("space"))
            {
                //sendData("space key was pressed");

                //var unixTimestamp = (DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalMilliseconds;
                //Debug.Log("unix time ms " + unixTimestamp);

                Debug.Log("time ms " + Time.time);
            }
        }
Example #18
0
 public void Push(SingleLinkNode <T> newNode)
 {
     newNode.Item = default(T);
     do
     {
         newNode.Next = head.Next;
     } while (!SyncMethods.CAS <SingleLinkNode <T> >(ref head.Next, newNode.Next, newNode));
     return;
 }
Example #19
0
            public void Push(T item)
            {
                SingleLinkNode <T> newNode = new SingleLinkNode <T>();

                newNode.Item = item;
                do
                {
                    newNode.Next = head.Next;
                } while (!SyncMethods.CAS <SingleLinkNode <T> >(ref head.Next, newNode.Next, newNode));
            }
        void clientGetData(string data)
        {
            // In order to get back to the main thread
            // (Unity cannot handle scene modifications on other threads),
            // we put the data in a concurrent pool
            SingleLinkNode <string> node = new SingleLinkNode <string>();

            node.Item = data;
            dataIn.Push(node);
            // Next part of the pipeline is DataHandler.Update()
        }
Example #21
0
        // Update is called once per frame
        void Update()
        {
            // Check Concurrent Pool for data
            SingleLinkNode <byte[]> node = null;

            if (dataIn.Pop(out node))
            {
                byte[] data = node.Item;
                getDataDelegate(data);
            }
        }
Example #22
0
 public bool MoveNext()
 {
     if (currentNode == null)
     {
         currentNode = parent.mHead.Next;
     }
     else
     {
         currentNode = currentNode.Next;
     }
     return(currentNode != null);
 }
Example #23
0
 public bool Pop(out SingleLinkNode <T> node)
 {
     do
     {
         node = head.Next;
         if (node == null)
         {
             return(false);
         }
     } while (!SyncMethods.CAS <SingleLinkNode <T> >(ref head.Next, node, node.Next));
     return(true);
 }
Example #24
0
        void getData(byte[] data)
        {
            //Debug.Log("getData() + " + data);


            // In order to get back to the main thread
            // (Unity cannot handle scene modifications on other threads),
            // we put the data in a concurrent pool
            SingleLinkNode <byte[]> node = new SingleLinkNode <byte[]>();

            node.Item = data;
            dataIn.Push(node);
            // Next part of the pipeline is DataServer.Update()
        }
        //--- Class Methods ---

        /// <summary>
        /// Add a named callback to the clock.
        /// </summary>
        /// <param name="name">Unique key for the callback.</param>
        /// <param name="callback">Callback action.</param>
        public static void AddCallback(string name, ClockCallback callback)
        {
            if (string.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException("name", "name cannot be null or empty");
            }
            if (callback == null)
            {
                throw new ArgumentNullException("callback");
            }

            // add callback
#if LOCKFREEE
            var newNode = new SingleLinkNode <NamedClockCallback>(new NamedClockCallback(name, callback));
            do
            {
                newNode.Next = _head;
            } while(!SysUtil.CAS(ref _head, newNode.Next, newNode));
#else
            lock (_syncRoot) {
                int index;

                // check if there is an empty slot in the callbacks array
                for (index = 0; index < _callbacks.Length; ++index)
                {
                    if (_callbacks[index].Value == null)
                    {
                        _callbacks[index] = new NamedClockCallback(name, callback);
                        return;
                    }
                }

                // make room to add a new thread by doubling the array size and copying over the existing entries
                var newArray = new NamedClockCallback[2 * _callbacks.Length];
                Array.Copy(_callbacks, newArray, _callbacks.Length);

                // assign new thread
                newArray[index] = new NamedClockCallback(name, callback);

                // update instance field
                _callbacks = newArray;
            }
#endif
        }
Example #26
0
        void Update(object sender, EventArgs e)
        {
            // Check Concurrent Pool for data
            List <byte[]>           dataList = new List <byte[]>();
            SingleLinkNode <byte[]> node     = null;

            while (BTDataIn.Pop(out node))
            {
                dataList.Add(node.Item);
            }
            if (dataList.Count > 0)
            {
                // Turn the LIFO list into a FIFO list
                dataList.Reverse();
                foreach (byte[] data in dataList)
                {
                    getBTData(data);
                }
            }
        }
        //--- Class Methods ---

        /// <summary>
        /// Add a named callback to the clock.
        /// </summary>
        /// <param name="name">Unique key for the callback.</param>
        /// <param name="callback">Callback action.</param>
        public static void AddCallback(string name, ClockCallback callback) {
            if(string.IsNullOrEmpty(name)) {
                throw new ArgumentNullException("name", "name cannot be null or empty");
            }
            if(callback == null) {
                throw new ArgumentNullException("callback");
            }

            // add callback
#if LOCKFREEE
            var newNode = new SingleLinkNode<NamedClockCallback>(new NamedClockCallback(name, callback));
            do {
                newNode.Next = _head;
            } while(!SysUtil.CAS(ref _head, newNode.Next, newNode));
#else
            lock(_syncRoot) {
                int index;

                // check if there is an empty slot in the callbacks array
                for(index = 0; index < _callbacks.Length; ++index) {
                    if(_callbacks[index].Value == null) {
                        _callbacks[index] = new NamedClockCallback(name, callback);
                        return;
                    }
                }

                // make room to add a new thread by doubling the array size and copying over the existing entries
                var newArray = new NamedClockCallback[2 * _callbacks.Length];
                Array.Copy(_callbacks, newArray, _callbacks.Length);

                // assign new thread
                newArray[index] = new NamedClockCallback(name, callback);

                // update instance field
                _callbacks = newArray;
            }
#endif
        }
Example #28
0
        public void Unshift(T pItem)
        {
            SingleLinkNode oldHead = null;

            var newNode = new SingleLinkNode();

            newNode.Item = pItem;

            var newNodeWasAdded = false;

            while (!newNodeWasAdded)
            {
                oldHead      = mHead.Next;
                newNode.Next = oldHead;

                if (mHead.Next == oldHead)
                {
                    newNodeWasAdded = CompareAndExchange(ref mHead.Next, oldHead, newNode);
                }
            }

            CompareAndExchange(ref mHead, oldHead, newNode);
        }
        /// <summary>
        /// Try to dequeue an item
        /// </summary>
        /// <param name="item">Dequeued item if the dequeue was successful</param>
        /// <returns>True if an item was successfully deqeued, otherwise false</returns>
        public bool TryDequeue(out T item)
        {
            while (true)
            {
                SingleLinkNode oldHead     = head;
                SingleLinkNode oldHeadNext = oldHead.Next;

                if (oldHead == head)
                {
                    if (oldHeadNext == null)
                    {
                        item  = default(T);
                        count = 0;
                        return(false);
                    }
                    if (CAS(ref head, oldHead, oldHeadNext))
                    {
                        item = oldHeadNext.Item;
                        Interlocked.Decrement(ref count);
                        return(true);
                    }
                }
            }
        }
Example #30
0
        /// <summary>
        /// Add character sequence to nametable and get the string instance it represents.
        /// </summary>
        /// <remarks>
        /// If the sequence already exists, the existing string instance is returned.
        /// </remarks>
        /// <param name="chars">Source character array.</param>
        /// <param name="offset">Offset in chars.</param>
        /// <param name="length">Length of sub-array from chars.</param>
        /// <returns>String instance for character sequence.</returns>
        public override string Add(char[] chars, int offset, int length)
        {
            // check for the empty string and always return the built-in constant for it
            if(length == 0) {
                return string.Empty;
            }

            // locate entry based on hashcode of the supplied token
            int hashcode = chars.GetAlternativeHashCode(offset, length);
            int index = GetIndex(hashcode);
            SingleLinkNode<Entry> current = _buckets[index];
            SingleLinkNode<Entry> entry = null;

            // check if a head node exists for the given hashcode
            if(current == null) {
                entry = new SingleLinkNode<Entry>(new Entry(hashcode, new string(chars, offset, length)));

                // try to update the head node with the new entry
                current = Interlocked.CompareExchange(ref _buckets[index], entry, null);

                // check if we succeeded, which means the provided token is now the reference token
                if(current == null) {
                    return entry.Item.Token;
                }

                // otherwise, continue on since 'current' now has the updated head node
            }

            // loop until we successfully find or append the token
            SingleLinkNode<Entry> previous = null;
            while(true) {

                // check if we're looking for a short string (in that case, we skip the hashcode check)
                if(length < 12) {

                    // loop over all entries until we exhaust them or find a match
                    for(; current != null; current = current.Next) {

                        // do only an ordinal string comparison since the token is short
                        if(CompareStringToCharArray(current.Item.Token, chars, offset, length) == 0) {
                            return current.Item.Token;
                        }
                        previous = current;
                    }
                } else {

                    // loop over all entries until we exhaust them or find a match
                    for(; current != null; current = current.Next) {

                        // do only an ordinal string comparison since the token is short
                        if((current.Item.HashCode == hashcode) && (CompareStringToCharArray(current.Item.Token, chars, offset, length) == 0)) {
                            return current.Item.Token;
                        }
                        previous = current;
                    }
                }

                // NOTE: it's possible that an earlier attempt already initialized 'entry'
                entry = entry ?? new SingleLinkNode<Entry>(new Entry(hashcode, new string(chars, offset, length)));

                // try to update the previous node with the new entry
                current = Interlocked.CompareExchange(ref previous.Next, entry, null);

                // check if we succeeded, which means the provided token is now the reference token
                if(current == null) {

                    // provided token was added
                    return entry.Item.Token;
                }

                // otherwise, continue on since 'current' now has the updated next node
            }
        }
        private static void MasterTickThread(object _unused)
        {
            DateTime last = DateTime.UtcNow;

            while (_running)
            {
                // wait until next iteration
                Thread.Sleep(_intervalMilliseconds);

                // get current time and calculate delta
                DateTime now     = DateTime.UtcNow;
                TimeSpan elapsed = now - last;
                last = now;

                // execute all callbacks
#if LOCKFREEE
                SingleLinkNode <NamedClockCallback> previous = null;
                var current = _head;
                while (current != null)
                {
                    var key      = current.Item.Key;
                    var callback = current.Item.Value;
                    if (callback == null)
                    {
                        // remove linked node
                        if (previous == null)
                        {
                            // there might be contention on the head item of the callback list;
                            // hence, we need to do it in a threadsafe fashion
                            SingleLinkNode <NamedClockCallback> head;
                            SingleLinkNode <NamedClockCallback> next;
                            do
                            {
                                head = _head;
                                next = head.Next;
                            } while(!SysUtil.CAS(ref _head, head, next));
                        }
                        else
                        {
                            // other threads don't operate on non-head items of the callback list
                            previous.Next = current.Next;
                        }

                        // clear out the item entirely to indicate we've removed it
                        current.Item = new NamedClockCallback(null, null);
                    }
                    else
                    {
                        try {
                            callback(now, elapsed);
                        } catch (Exception e) {
                            _log.ErrorExceptionMethodCall(e, "GlobalClock callback failed", key);
                        }
                    }
                    previous = current;
                    current  = current.Next;
                }
#else
                lock (_syncRoot) {
                    var callbacks = _callbacks;
                    foreach (NamedClockCallback callback in callbacks)
                    {
                        if (callback.Value != null)
                        {
                            try {
                                callback.Value(now, elapsed);
                            } catch (Exception e) {
                                _log.ErrorExceptionMethodCall(e, "GlobalClock callback failed", callback.Key);
                            }
                        }
                    }
                }
#endif
            }

            // indicate that this thread has exited
            _stopped.Set();
        }
Example #32
0
 private static bool CompareAndExchange(ref SingleLinkNode pLocation, SingleLinkNode pComparand, SingleLinkNode pNewValue)
 {
     return
         (pComparand ==
          Interlocked.CompareExchange(ref pLocation, pNewValue, pComparand));
 }
Example #33
0
 public void Reset()
 {
     currentNode = parent.mHead.Next;
 }