예제 #1
0
        public static void Clear(UnsafeMPMCQueue *queue)
        {
            UDebug.Assert(queue != null);
            UDebug.Assert(queue->_head != null);

            queue->_crossSegmentLock.Lock();
            queue->_tail->EnsureFrozenForEnqueues();

            var segmentsize = INITIAL_SEGMENT_LENGTH;

            if (queue->_fixedSize)
            {
                segmentsize = queue->_tail->Capacity;
            }

            // Free all segments
            var segment = queue->_head;

            do
            {
                var next = segment->_nextSegment;
                QueueSegment.Free(segment);
                segment = next;
            }while (segment != null);

            queue->_tail = queue->_head = QueueSegment.Allocate(segmentsize, queue->_slotStride, queue->_slotOffset);

            queue->_crossSegmentLock.Unlock();
        }
예제 #2
0
        private bool TryDequeueSlow <T>(out T result) where T : unmanaged
        {
            while (true)
            {
                QueueSegment *head = _head;

                if (head->TryDequeue(out result))
                {
                    return(true);
                }

                if (head->_nextSegment == null)
                {
                    result = default;
                    return(false);
                }

                UDebug.Assert(head->_frozen);

                if (head->TryDequeue(out result))
                {
                    return(true);
                }

                _crossSegmentLock.Lock();
                if (head == _head)
                {
                    var next = head->_nextSegment;
                    QueueSegment.Free(head);

                    _head = next;
                }
                _crossSegmentLock.Unlock();
            }
        }
예제 #3
0
        public static void Free(UnsafeMPMCQueue *queue)
        {
            if (queue == null)
            {
                return;
            }

            // Free all segments
            var segment = queue->_head;

            do
            {
                var next = segment->_nextSegment;
                QueueSegment.Free(segment);
                segment = next;
            }while (segment != null);

            // Clear queue memory (just in case)
            *queue = default;

            // Free queue memory, if this is a fixed queue it frees the items memory at the same time
            Memory.Free(queue);
        }