public BlockStream(int foreachCount, uint uniqueBlockStreamId, Allocator allocator = Allocator.TempJob)
        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            if (foreachCount <= 0)
            {
                throw new ArgumentException("foreachCount must be > 0", "foreachCount");
            }
            if (allocator <= Allocator.None)
            {
                throw new ArgumentException("Allocator must be Temp, TempJob or Persistent", "allocator");
            }
#endif

            m_Block               = null;
            m_AllocatorLabel      = allocator;
            m_UniqueBlockStreamId = uniqueBlockStreamId;

            int blockCount = JobsUtility.MaxJobThreadCount;

            int   allocationSize = sizeof(BlockStreamData) + sizeof(Block *) * blockCount + sizeof(Range) * foreachCount;
            byte *buffer         = (byte *)UnsafeUtility.Malloc(allocationSize, 16, m_AllocatorLabel);
            UnsafeUtility.MemClear(buffer, allocationSize);

            m_Block             = (BlockStreamData *)buffer;
            m_Block->Allocator  = m_AllocatorLabel;
            m_Block->BlockCount = blockCount;
            m_Block->Blocks     = (Block **)(buffer + sizeof(BlockStreamData));

            m_Block->Ranges     = (Range *)((byte *)m_Block->Blocks + sizeof(Block *) * blockCount);
            m_Block->RangeCount = foreachCount;

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            DisposeSentinel.Create(out m_Safety, out m_DisposeSentinel, 0, m_AllocatorLabel);
#endif
        }
Exemple #2
0
        public JobHandle Dispose(JobHandle inputDeps)
        {
            // [DeallocateOnJobCompletion] is not supported, but we want the deallocation to happen in a thread.
            // DisposeSentinel needs to be cleared on main thread.
            // AtomicSafetyHandle can be destroyed after the job was scheduled (Job scheduling will check that no jobs are writing to the container)
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            DisposeSentinel.Clear(ref m_DisposeSentinel);
#endif
            var jobHandle = new DisposeJob {
                BlockStream = this
            }.Schedule(inputDeps);
            m_Block = null;

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            AtomicSafetyHandle.Release(m_Safety);
#endif

            return(jobHandle);
        }
Exemple #3
0
            internal Writer(ref NativeStream stream)
            {
                m_BlockStream     = stream.m_Block;
                m_ForeachIndex    = int.MinValue;
                m_ElementCount    = -1;
                m_CurrentBlock    = null;
                m_CurrentBlockEnd = null;
                m_CurrentPtr      = null;
                m_FirstBlock      = null;
                m_NumberOfBlocks  = 0;
                m_FirstOffset     = 0;
                m_ThreadIndex     = 0;

#if ENABLE_UNITY_COLLECTIONS_CHECKS
                m_Safety         = stream.m_Safety;
                m_Length         = int.MaxValue;
                m_MinIndex       = int.MinValue;
                m_MaxIndex       = int.MinValue;
                m_PassByRefCheck = null;
#endif
            }
        private void _Dispose()
        {
            if (m_Block == null)
            {
                return;
            }

            for (int i = 0; i != m_Block->BlockCount; i++)
            {
                Block *block = m_Block->Blocks[i];
                while (block != null)
                {
                    Block *next = block->Next;
                    UnsafeUtility.Free(block, m_AllocatorLabel);
                    block = next;
                }
            }

            UnsafeUtility.Free(m_Block, m_AllocatorLabel);
            m_Block = null;
        }
Exemple #5
0
        void Deallocate()
        {
            if (m_Block == null)
            {
                return;
            }

            for (int i = 0; i != m_Block->BlockCount; i++)
            {
                Block *block = m_Block->Blocks[i];
                while (block != null)
                {
                    Block *next = block->Next;
                    UnsafeUtility.Free(block, m_AllocatorLabel);
                    block = next;
                }
            }

            UnsafeUtility.Free(m_Block->Ranges, m_AllocatorLabel);
            UnsafeUtility.Free(m_Block, m_AllocatorLabel);
            m_Block          = null;
            m_AllocatorLabel = Allocator.Invalid;
        }