コード例 #1
0
        /// <summary>
        /// Pop an item from the head of the queue.
        /// </summary>
        /// <remarks>
        /// NOTE: TrySteal() can be invoked from any thread.
        /// </remarks>
        /// <param name="item">Head item of the queue when operation is successful.</param>
        /// <returns><see langword="True"/> if operation was successful.</returns>
        public bool TrySteal(out T item)
        {
            // read top
            TopData curTop = _top;

            // read bottom
            BottomData curBottom = _bottom;

            if (IsEmpty(curBottom, curTop, _capacity))
            {
                item = default(T);
                if (ReferenceEquals(curTop, _top))
                {
                    return(false);
                }
                else
                {
                    // NOTE (steveb): this is contentious access case; we currently return 'false' but may want to differentiate in the future
                    return(false);
                }
            }

            // if deque isn't empty, calcuate next top pointer
            TopData newTop;

            if (curTop.Index != 0)
            {
                // stay at current node
                newTop = new TopData(curTop.Tag, curTop.Node, curTop.Index - 1);
            }
            else
            {
                // move to next node and update tag
                newTop = new TopData(curTop.Tag + 1, curTop.Node.Prev, _capacity - 1);
            }

            // read value
            T retVal = curTop.Node.Data[curTop.Index];

            // try updating _top using CAS
            if (SysUtil.CAS(ref _top, curTop, newTop))
            {
                // clear out the entry we read, so the GC can reclaim it
                SysUtil.CAS(ref curTop.Node.Data[curTop.Index], retVal, default(T));

                // free old node
                curTop.Node.Next = null;
                item             = retVal;
                return(true);
            }
            else
            {
                item = default(T);

                // NOTE (steveb): this is contentious access case; we currently return 'false' but may want to differentiate in the future
                return(false);
            }
        }
コード例 #2
0
        /// <summary>
        /// Create a new instance.
        /// </summary>
        /// <param name="capacity">Maximum number of items in the queue.</param>
        public WorkStealingDeque(int capacity)
        {
            _capacity = capacity;
            DequeNode nodeB = new DequeNode(_capacity, null);
            DequeNode nodeA = new DequeNode(_capacity, nodeB);

            _bottom = new BottomData(nodeA, _capacity - 1);
            _top    = new TopData(0, nodeA, _capacity - 1);
        }
コード例 #3
0
 //--- Class Methods ---
 private static bool IsEmpty(BottomData bottom, TopData top, int capacity)
 {
     if (ReferenceEquals(bottom.Node, top.Node) && ((bottom.Index == top.Index) || (bottom.Index == (top.Index + 1))))
     {
         return(true);
     }
     else if (ReferenceEquals(bottom.Node, top.Node.Next) && (bottom.Index == 0) && (top.Index == (capacity - 1)))
     {
         return(true);
     }
     return(false);
 }
コード例 #4
0
            static public void ShowPanel(List <KeyValuePair <string, string> > showText, string imageLocation, Control panel2)
            {
                BottomData bottomData;

                ///创建BottomData
                if (!_dicBottomData.TryGetValue(showText.Count + (string.IsNullOrEmpty(imageLocation) ? 0 : 10000), out bottomData))
                {
                    ///初始化bottomData
                    if (string.IsNullOrEmpty(imageLocation))
                    {
                        bottomData = new BottomData(panel2, new TableLayoutPanel(), new KeyValuePair <Control, Control> [showText.Count]);
                    }
                    else
                    {
                        bottomData = new BottomData(panel2, new TableLayoutPanel(), new KeyValuePair <Control, Control> [showText.Count], new PictureBox(), new SplitContainer());
                    }
                    _dicBottomData.Add(showText.Count + (string.IsNullOrEmpty(imageLocation) ? 0 : 10000), bottomData);
                }

                ///将其添加到底部
                if (bottomData.HasImage)
                {
                    if (panel2.Controls.Count == 0 || panel2.Controls[0] != bottomData.ImageSplitContainer)
                    {
                        panel2.Controls.Clear();
                        panel2.Controls.Add(bottomData.ImageSplitContainer);
                    }
                }
                else
                {
                    if (panel2.Controls.Count == 0 || panel2.Controls[0] != bottomData.MainTableLayoutPanel)
                    {
                        panel2.Controls.Clear();
                        panel2.Controls.Add(bottomData.MainTableLayoutPanel);
                    }
                }

                ///设置Text值
                KeyValuePair <Control, Control>[] keyvalues = bottomData.KeyValueControls;
                for (int i = 0; i < showText.Count; i++)
                {
                    keyvalues[i].Key.Text   = showText[i].Key;
                    keyvalues[i].Value.Text = showText[i].Value;
                }

                ///设置图片地址
                if (!string.IsNullOrEmpty(imageLocation))
                {
                    bottomData.PictureBox.ImageLocation = imageLocation;
                }
            }
コード例 #5
0
        //--- Methods ---

        /// <summary>
        /// Push an item onto the tail of the queue.
        /// </summary>
        /// <remarks>
        /// NOTE: Push() and TryPop() <strong>MUST</strong> be called from the same thread.
        /// </remarks>
        /// <param name="data">Item to push onto the tail of the queue.</param>
        public void Push(T data)
        {
            // read bottom data
            BottomData curBottom = _bottom;

            // write data in current bottom cell
            curBottom.Node.Data[curBottom.Index] = data;
            BottomData newBottom;

            if (curBottom.Index != 0)
            {
                newBottom = new BottomData(curBottom.Node, curBottom.Index - 1);
            }
            else
            {
                // allocate and link a new node
                DequeNode newNode = new DequeNode(_capacity, curBottom.Node);
                newBottom = new BottomData(newNode, _capacity - 1);
            }

            // update bottom
            _bottom = newBottom;
        }
コード例 #6
0
    private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        BottomData bd = d as BottomData;

        bd.NotifyPropertyChanged("Value");
    }
コード例 #7
0
        /// <summary>
        /// Pop an item from the tail of the queue.
        /// </summary>
        /// <remarks>
        /// NOTE: Push() and TryPop() <strong>MUST</strong> be called from the same thread.
        /// </remarks>
        /// <param name="item">Tail item of the queue when operation is successful.</param>
        /// <returns><see langword="True"/> if operation was successful.</returns>
        public bool TryPop(out T item)
        {
            item = default(T);

            // read bottom data
            BottomData curBottom = _bottom;
            BottomData newBottom;

            if (curBottom.Index != (_capacity - 1))
            {
                newBottom = new BottomData(curBottom.Node, curBottom.Index + 1);
            }
            else
            {
                newBottom = new BottomData(curBottom.Node.Next, 0);
            }

            // update bottom
            _bottom = newBottom;

            // read top
            TopData curTop = _top;

            // read data to be popped
            T retVal = newBottom.Node.Data[newBottom.Index];

            // case 1: if _top has crossed _bottom
            if (ReferenceEquals(curBottom.Node, curTop.Node) && (curBottom.Index == curTop.Index))
            {
                // return bottom to its old position
                _bottom = curBottom;
                return(false);
            }

            // case 2: when popping the last entry in the deque (i.e. deque is empty after the update of bottom)
            if (ReferenceEquals(newBottom.Node, curTop.Node) && (newBottom.Index == curTop.Index))
            {
                // try to update _top's tag so no concurrent Steal operation will also pop the same entry
                TopData newTopVal = new TopData(curTop.Tag + 1, curTop.Node, curTop.Index);
                if (SysUtil.CAS(ref _top, curTop, newTopVal))
                {
                    // TODO (steveb): clear out the entry we read, so the GC can reclaim it

                    // free old node if needed
                    if (!ReferenceEquals(curBottom.Node, newBottom.Node))
                    {
                        newBottom.Node.Prev = null;
                    }
                    item = retVal;
                    return(true);
                }
                else
                {
                    // if CAS failed (i.e. a concurrent Steal operation alrady popped that last entry)

                    // return bottom to its old position
                    _bottom = curBottom;
                    return(false);
                }
            }

            // case 3: regular case (i.e. there was a least one entry in the deque _after_ bottom's update)
            // free old node if needed
            if (!ReferenceEquals(curBottom.Node, newBottom.Node))
            {
                newBottom.Node.Prev = null;
            }
            item = retVal;
            return(true);
        }