Exemplo n.º 1
0
 public unsafe static void Release(NativeQueueBlockHeader *block, NativeQueueBlockPoolData *pool)
 {
     if (0 == Interlocked.Decrement(ref block->m_NumReaders))
     {
         pool->FreeBlock(block);
     }
 }
        public static byte *AllocateWriteBlockMT <T>(NativeQueueData *data, NativeQueueBlockPoolData *pool, int threadIndex) where T : struct
        {
            int tlsIdx = threadIndex;

            byte *currentWriteBlock = data->m_CurrentWriteBlockTLS[tlsIdx * IntsPerCacheLine];

            if (currentWriteBlock != null && ((NativeQueueBlockHeader *)currentWriteBlock)->itemsInBlock == data->m_ItemsPerBlock)
            {
                currentWriteBlock = null;
            }
            if (currentWriteBlock == null)
            {
                currentWriteBlock = pool->AllocateBlock();
                ((NativeQueueBlockHeader *)currentWriteBlock)->nextBlock    = null;
                ((NativeQueueBlockHeader *)currentWriteBlock)->itemsInBlock = 0;
                NativeQueueBlockHeader *prevLast = (NativeQueueBlockHeader *)Interlocked.Exchange(ref data->m_LastBlock, (IntPtr)currentWriteBlock);
                if (prevLast == null)
                {
                    data->m_FirstBlock = currentWriteBlock;
                }
                else
                {
                    prevLast->nextBlock = currentWriteBlock;
                }
                data->m_CurrentWriteBlockTLS[tlsIdx * IntsPerCacheLine] = currentWriteBlock;
            }
            return(currentWriteBlock);
        }
Exemplo n.º 3
0
        public static byte *AllocateWriteBlockMT <T>(NativeQueueData *data, NativeQueueBlockPoolData *pool, int threadIndex) where T : struct
        {
            int tlsIdx = threadIndex;

            NativeQueueBlockHeader *currentWriteBlock = (NativeQueueBlockHeader *)data->GetCurrentWriteBlockTLS(tlsIdx);

            if (currentWriteBlock != null &&
                currentWriteBlock->itemsInBlock == data->m_ItemsPerBlock)
            {
                currentWriteBlock = null;
            }

            if (currentWriteBlock == null)
            {
                currentWriteBlock               = (NativeQueueBlockHeader *)pool->AllocateBlock();
                currentWriteBlock->nextBlock    = null;
                currentWriteBlock->itemsInBlock = 0;
                NativeQueueBlockHeader *prevLast = (NativeQueueBlockHeader *)Interlocked.Exchange(ref data->m_LastBlock, (IntPtr)currentWriteBlock);

                if (prevLast == null)
                {
                    data->m_FirstBlock = currentWriteBlock;
                }
                else
                {
                    prevLast->nextBlock = currentWriteBlock;
                }

                data->SetCurrentWriteBlockTLS(tlsIdx, currentWriteBlock);
            }

            return((byte *)currentWriteBlock);
        }
        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);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Constructs a new queue with type of memory allocation.
        /// </summary>
        /// <param name="allocator">A member of the
        /// [Unity.Collections.Allocator](https://docs.unity3d.com/ScriptReference/Unity.Collections.Allocator.html) enumeration.</param>
        public NativeQueue(Allocator allocator)
        {
            CollectionHelper.CheckIsUnmanaged <T>();

            m_QueuePool      = NativeQueueBlockPool.QueueBlockPool;
            m_AllocatorLabel = allocator;

            NativeQueueData.AllocateQueue <T>(allocator, out m_Buffer);

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            DisposeSentinel.Create(out m_Safety, out m_DisposeSentinel, 0, allocator);
#endif
        }
Exemplo n.º 6
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);
        }
Exemplo n.º 7
0
        public unsafe NativeQueue(Allocator label)
        {
            m_QueuePool = NativeQueueBlockPool.QueueBlockPool;
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            if (!UnsafeUtility.IsBlittable <T>())
            {
                throw new ArgumentException(string.Format("{0} used in NativeQueue<{0}> must be blittable", typeof(T)));
            }
#endif
            m_AllocatorLabel = label;

            NativeQueueData.AllocateQueue <T>(label, out m_Buffer);

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            DisposeSentinel.Create(out m_Safety, out m_DisposeSentinel, 0);
#endif
        }
Exemplo n.º 8
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);
        }
Exemplo n.º 9
0
        /// <summary>
        /// Constructs a new queue with type of memory allocation.
        /// </summary>
        /// <param name="allocator">A member of the
        /// [Unity.Collections.Allocator](https://docs.unity3d.com/ScriptReference/Unity.Collections.Allocator.html) enumeration.</param>
        public NativeQueue(Allocator allocator)
        {
            CollectionHelper.CheckIsUnmanaged <T>();

            m_QueuePool      = NativeQueueBlockPool.QueueBlockPool;
            m_AllocatorLabel = allocator;

            NativeQueueData.AllocateQueue <T>(allocator, out m_Buffer);

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            DisposeSentinel.Create(out m_Safety, out m_DisposeSentinel, 0, allocator);

            if (s_staticSafetyId.Data == 0)
            {
                CreateStaticSafetyId();
            }
            AtomicSafetyHandle.SetStaticSafetyId(ref m_Safety, s_staticSafetyId.Data);
#endif
        }
Exemplo n.º 10
0
        public static NativeQueueBlockHeader *AllocateWriteBlockMT <T>(NativeQueueData *data, NativeQueueBlockPoolData *pool, int threadIndex) where T : struct
        {
            NativeQueueBlockHeader *currentWriteBlock = data->GetCurrentWriteBlockTLS(threadIndex);

            if (currentWriteBlock != null &&
                currentWriteBlock->m_NumItems == data->m_MaxItems)
            {
                currentWriteBlock = null;
            }

            if (currentWriteBlock == null)
            {
                currentWriteBlock = pool->AllocateBlock();
                currentWriteBlock->m_NextBlock = null;
                currentWriteBlock->m_NumItems  = 0;
                NativeQueueBlockHeader *prevLast = (NativeQueueBlockHeader *)Interlocked.Exchange(ref data->m_LastBlock, (IntPtr)currentWriteBlock);

                if (prevLast == null)
                {
                    data->m_FirstBlock = (IntPtr)currentWriteBlock;
                }
                else
                {
                    prevLast->m_NextBlock = currentWriteBlock;
                }

                data->SetCurrentWriteBlockTLS(threadIndex, currentWriteBlock);
            }

            return(currentWriteBlock);
        }