Example #1
0
        /// <summary>
        /// Enqueue value into the container.
        /// </summary>
        /// <param name="value">The value to be appended.</param>
        public void Enqueue(T value)
        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            AtomicSafetyHandle.CheckWriteAndThrow(m_Safety);
#endif
            NativeQueueBlockHeader *writeBlock = NativeQueueData.AllocateWriteBlockMT <T>(m_Buffer, m_QueuePool, 0);
            UnsafeUtility.WriteArrayElement(writeBlock + 1, writeBlock->m_NumItems, value);
            ++writeBlock->m_NumItems;
        }
Example #2
0
        /// <summary>
        /// Enqueue value into the container.
        /// </summary>
        /// <param name="value">The value to be appended.</param>
        public void Enqueue(T value)
        {
            CheckWrite();

            NativeQueueBlockHeader *writeBlock = NativeQueueData.AllocateWriteBlockMT <T>(m_Buffer, m_QueuePool, 0);

            UnsafeUtility.WriteArrayElement(writeBlock + 1, writeBlock->m_NumItems, value);
            ++writeBlock->m_NumItems;
        }
 static void OnDomainUnload(object sender, EventArgs e)
 {
     while (data.firstBlock != IntPtr.Zero)
     {
         NativeQueueBlockHeader *block = (NativeQueueBlockHeader *)data.firstBlock;
         data.firstBlock = (IntPtr)(block->nextBlock);
         UnsafeUtility.Free(block, Allocator.Persistent);
         --data.allocatedBlocks;
     }
 }
        public unsafe static void DeallocateQueue(NativeQueueData *data, NativeQueueBlockPoolData *pool, Allocator allocation)
        {
            NativeQueueBlockHeader *firstBlock = (NativeQueueBlockHeader *)data->m_FirstBlock;

            while (firstBlock != null)
            {
                NativeQueueBlockHeader *next = (NativeQueueBlockHeader *)firstBlock->nextBlock;
                pool->FreeBlock((byte *)firstBlock);
                firstBlock = next;
            }
            UnsafeUtility.Free(data, allocation);
        }
Example #5
0
        public unsafe static void DeallocateQueue(NativeQueueData *data, NativeQueueBlockPoolData *pool, Allocator allocation)
        {
            NativeQueueBlockHeader *firstBlock = (NativeQueueBlockHeader *)data->m_FirstBlock;

            while (firstBlock != null)
            {
                NativeQueueBlockHeader *next = firstBlock->m_NextBlock;
                pool->FreeBlock(firstBlock);
                firstBlock = next;
            }

            Memory.Unmanaged.Free(data, allocation);
        }
Example #6
0
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public T Peek()
        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            AtomicSafetyHandle.CheckReadAndThrow(m_Safety);
#endif
            NativeQueueBlockHeader *firstBlock = (NativeQueueBlockHeader *)m_Buffer->m_FirstBlock;

            if (firstBlock == null)
            {
                throw new InvalidOperationException("Trying to peek from an empty queue");
            }

            return(UnsafeUtility.ReadArrayElement <T>(firstBlock + 1, m_Buffer->m_CurrentRead));
        }
Example #7
0
        public static NativeQueueBlockHeader *GetFirstBlock(NativeQueueData *data, NativeQueueBlockPoolData *pool)
        {
            NativeQueueBlockHeader *firstBlock = (NativeQueueBlockHeader *)data->m_FirstBlock;

            if (firstBlock == null)
            {
                return(null);
            }

            if (data->m_CurrentRead >= firstBlock->m_NumItems)
            {
                var nextBlock = firstBlock->m_NextBlock;

                // Block should be freed once last reader calls Release.
                Interlocked.Decrement(ref firstBlock->m_NumReaders);

                for (int threadIndex = 0; threadIndex < JobsUtility.MaxJobThreadCount; ++threadIndex)
                {
                    if (data->GetCurrentWriteBlockTLS(threadIndex) == firstBlock)
                    {
                        data->SetCurrentWriteBlockTLS(threadIndex, null);
                    }
                }

                firstBlock = nextBlock;

                data->m_FirstBlock  = (IntPtr)nextBlock;
                data->m_CurrentRead = 0;

                if (nextBlock == null)
                {
                    data->m_LastBlock = IntPtr.Zero;
                }
            }

            if (firstBlock == null)
            {
                return(null);
            }

            Interlocked.Increment(ref firstBlock->m_NumReaders);

            return(firstBlock);
        }
        unsafe public void Clear()
        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            AtomicSafetyHandle.CheckWriteAndThrow(m_Safety);
#endif
            NativeQueueBlockHeader *firstBlock = (NativeQueueBlockHeader *)m_Buffer->m_FirstBlock;
            while (firstBlock != null)
            {
                NativeQueueBlockHeader *next = (NativeQueueBlockHeader *)firstBlock->nextBlock;
                m_QueuePool->FreeBlock((byte *)firstBlock);
                firstBlock = next;
            }
            m_Buffer->m_FirstBlock = null;
            m_Buffer->m_LastBlock  = IntPtr.Zero;
            m_Buffer->m_CurrentReadIndexInBlock = 0;
            for (int tls = 0; tls < JobsUtility.MaxJobThreadCount; ++tls)
            {
                m_Buffer->m_CurrentWriteBlockTLS[tls * NativeQueueData.IntsPerCacheLine] = null;
            }
        }
Example #9
0
        unsafe public bool TryDequeue(out T item)
        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            AtomicSafetyHandle.CheckWriteAndThrow(m_Safety);
#endif
            NativeQueueBlockHeader *firstBlock = NativeQueueData.GetFirstBlock(m_Buffer, m_QueuePool);

            if (firstBlock == null)
            {
                item = default(T);
                return(false);
            }

            var currentRead = m_Buffer->m_CurrentRead++;
            item = UnsafeUtility.ReadArrayElement <T>(firstBlock + 1, currentRead);

            NativeQueueData.Release(firstBlock, m_QueuePool);

            return(true);
        }
Example #10
0
        /// <summary>
        /// Try dequeueing item from the container. If container is empty item won't be changed, and return result will be false.
        /// </summary>
        /// <param name="item">Item value if dequeued.</param>
        /// <returns>Returns true if item was dequeued.</returns>
        public bool TryDequeue(out T item)
        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            AtomicSafetyHandle.CheckWriteAndThrow(m_Safety);
#endif

            NativeQueueBlockHeader *firstBlock = (NativeQueueBlockHeader *)m_Buffer->m_FirstBlock;

            if (firstBlock == null)
            {
                item = default(T);
                return(false);
            }

            var currentRead = m_Buffer->m_CurrentRead++;
            item = UnsafeUtility.ReadArrayElement <T>(firstBlock + 1, currentRead);

            if (m_Buffer->m_CurrentRead >= firstBlock->m_NumItems)
            {
                m_Buffer->m_CurrentRead = 0;
                m_Buffer->m_FirstBlock  = (IntPtr)firstBlock->m_NextBlock;

                if (m_Buffer->m_FirstBlock == IntPtr.Zero)
                {
                    m_Buffer->m_LastBlock = IntPtr.Zero;
                }

                for (int threadIndex = 0; threadIndex < JobsUtility.MaxJobThreadCount; ++threadIndex)
                {
                    if (m_Buffer->GetCurrentWriteBlockTLS(threadIndex) == firstBlock)
                    {
                        m_Buffer->SetCurrentWriteBlockTLS(threadIndex, null);
                    }
                }

                m_QueuePool->FreeBlock(firstBlock);
            }

            return(true);
        }
Example #11
0
        /// <summary>
        /// Clears the container.
        /// </summary>
        public void Clear()
        {
            CheckWrite();

            NativeQueueBlockHeader *firstBlock = (NativeQueueBlockHeader *)m_Buffer->m_FirstBlock;

            while (firstBlock != null)
            {
                NativeQueueBlockHeader *next = firstBlock->m_NextBlock;
                m_QueuePool->FreeBlock(firstBlock);
                firstBlock = next;
            }

            m_Buffer->m_FirstBlock  = IntPtr.Zero;
            m_Buffer->m_LastBlock   = IntPtr.Zero;
            m_Buffer->m_CurrentRead = 0;

            for (int threadIndex = 0; threadIndex < JobsUtility.MaxJobThreadCount; ++threadIndex)
            {
                m_Buffer->SetCurrentWriteBlockTLS(threadIndex, null);
            }
        }
Example #12
0
        public void FreeBlock(NativeQueueBlockHeader *block)
        {
            if (m_NumBlocks > m_MaxBlocks)
            {
                if (Interlocked.Decrement(ref m_NumBlocks) + 1 > m_MaxBlocks)
                {
                    UnsafeUtility.Free(block, Allocator.Persistent);
                    return;
                }

                Interlocked.Increment(ref m_NumBlocks);
            }

            NativeQueueBlockHeader *checkBlock = (NativeQueueBlockHeader *)m_FirstBlock;
            NativeQueueBlockHeader *nextPtr;

            do
            {
                nextPtr            = checkBlock;
                block->m_NextBlock = checkBlock;
                checkBlock         = (NativeQueueBlockHeader *)Interlocked.CompareExchange(ref m_FirstBlock, (IntPtr)block, (IntPtr)checkBlock);
            }while (checkBlock != nextPtr);
        }
Example #13
0
        /// <summary>
        /// Clears the container.
        /// </summary>
        public void Clear()
        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            AtomicSafetyHandle.CheckWriteAndThrow(m_Safety);
#endif
            NativeQueueBlockHeader *firstBlock = (NativeQueueBlockHeader *)m_Buffer->m_FirstBlock;

            while (firstBlock != null)
            {
                NativeQueueBlockHeader *next = firstBlock->m_NextBlock;
                m_QueuePool->FreeBlock(firstBlock);
                firstBlock = next;
            }

            m_Buffer->m_FirstBlock  = IntPtr.Zero;
            m_Buffer->m_LastBlock   = IntPtr.Zero;
            m_Buffer->m_CurrentRead = 0;

            for (int threadIndex = 0; threadIndex < JobsUtility.MaxJobThreadCount; ++threadIndex)
            {
                m_Buffer->SetCurrentWriteBlockTLS(threadIndex, null);
            }
        }
Example #14
0
        internal void SetCurrentWriteBlockTLS(int threadIndex, NativeQueueBlockHeader *currentWriteBlock)
        {
            var data = (NativeQueueBlockHeader **)&m_CurrentWriteBlockTLS[threadIndex * JobsUtility.CacheLineSize];

            *data = currentWriteBlock;
        }