Beispiel #1
0
        public byte *Allocate(int bytesToAllocate, int alignment)
        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            if (bytesToAllocate > ms_BlockSize)
            {
                throw new ArgumentException($"Cannot allocate more than {ms_BlockSize} in BlockAllocator. Requested: {bytesToAllocate}");
            }
#endif
            var nextByteOffsetAligned = (m_nextByteOffset + alignment - 1) & ~(alignment - 1);
            var nextBlockSize         = nextByteOffsetAligned + bytesToAllocate;
            if (m_blocks.Length == 0 || nextBlockSize > ms_BlockSize)
            {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                if (m_blocks.Length == m_blocks.Capacity)
                {
                    throw new ArgumentException($"Cannot exceed budget of {ms_BudgetInBytes} in BlockAllocator.");
                }
#endif
                // Allocate a fresh block of memory
                m_blocks.Add((byte *)AllocatorManager.Allocate(m_handle, sizeof(byte), ms_BlockAlignment, ms_BlockSize));
                m_allocations.Add(0);
                nextByteOffsetAligned = 0;
            }
            var blockIndex = m_blocks.Length - 1;

            var pointer = (byte *)m_blocks[blockIndex] + nextByteOffsetAligned;
            m_nextByteOffset = nextByteOffsetAligned + bytesToAllocate;
            m_allocations.Ptr[blockIndex]++;
            return(pointer);
        }
Beispiel #2
0
            /// <summary>
            /// Constructs an allocator.
            /// </summary>
            /// <param name="budgetInBytes">Budget of the allocator in bytes.</param>
            /// <param name="bufferSizeInBytes">Size of each buffer to be allocated in bytes.</param>
            /// <param name="handle">An AllocatorHandle to use for internal bookkeeping structures.</param>
            /// <exception cref="InvalidOperationException">Thrown if the allocator cannot reserve the address range required for the given budget.</exception>
            public BufferAllocator(int budgetInBytes, int bufferSizeInBytes, AllocatorManager.AllocatorHandle handle)
            {
                BufferSizeInBytes = bufferSizeInBytes;

                // Reserve the entire budget's worth of address space. The reserved space may be larger than the budget
                // due to page sizes.
                var pageCount = VirtualMemoryUtility.BytesToPageCount((uint)budgetInBytes, VirtualMemoryUtility.DefaultPageSizeInBytes);
                BaselibErrorState errorState;

                ReservedRange = VirtualMemoryUtility.ReserveAddressSpace(pageCount, VirtualMemoryUtility.DefaultPageSizeInBytes, out errorState);

#if ENABLE_UNITY_COLLECTIONS_CHECKS
                if (!errorState.Success)
                {
                    throw new InvalidOperationException($"Failed to reserve address range for {budgetInBytes} bytes");
                }
#endif

                // Init a free list of blocks.
                MaxBufferCount = (int)VirtualMemoryUtility.BytesToPageCount((uint)budgetInBytes, (uint)bufferSizeInBytes);
                FreeList       = new UnsafeIntList(MaxBufferCount, handle);

                for (int i = MaxBufferCount - 1; i >= 0; --i)
                {
                    FreeList.Add(i);
                }
            }
        public static bool AddReaderTypeIndex(int typeIndex, ref UnsafeIntList reading, ref UnsafeIntList writing)
        {
            if (reading.Contains(typeIndex))
            {
                return(false);
            }
            if (writing.Contains(typeIndex))
            {
                return(false);
            }

            reading.Add(typeIndex);
            return(true);
        }
Beispiel #4
0
        public BlockAllocator(AllocatorManager.AllocatorHandle handle, int budgetInBytes)
        {
            m_bufferAllocator = new BufferAllocator(budgetInBytes, ms_BlockSize, handle);
            m_nextPtr         = 0;
            var blocks = (budgetInBytes + ms_BlockSize - 1) >> ms_Log2BlockSize;

            m_allocations = new UnsafeIntList(blocks, handle);

            for (int i = 0; i < blocks; ++i)
            {
                m_allocations.Add(0);
            }

            m_currentBlockIndex = -1;
        }
        public static bool AddWriterTypeIndex(int typeIndex, ref UnsafeIntList reading, ref UnsafeIntList writing)
        {
            if (writing.Contains(typeIndex))
            {
                return(false);
            }

            var readingIndex = reading.IndexOf(typeIndex);

            if (readingIndex != -1)
            {
                reading.RemoveAtSwapBack(readingIndex);
            }

            writing.Add(typeIndex);
            return(true);
        }
Beispiel #6
0
            /// <summary>
            /// Frees the buffer represented by the given index.
            /// </summary>
            /// <param name="index">Index to buffer.</param>
            /// <exception cref="ArgumentException">Thrown when index is less than zero or when greater than or equal to BufferCapacity</exception>
            /// <exception cref="InvalidOperationException">Thrown if the buffer cannot be decommitted.</exception>
            public void Free(int index)
            {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                if (index < 0 || index >= BufferCapacity)
                {
                    throw new ArgumentException($"Cannot free index {index}, it is outside the expected range [0, {BufferCapacity}).");
                }
#endif
                BaselibErrorState errorState;
                var range = new VMRange((IntPtr)this[index], (uint)BufferSizeInBytes, VirtualMemoryUtility.DefaultPageSizeInBytes);
                VirtualMemoryUtility.DecommitMemory(range, out errorState);

                if (!errorState.Success)
                {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                    throw new InvalidOperationException($"Failed to decommit address range {range}.");
#endif
                }

                FreeList.Add(index);
            }
        public byte *Allocate(int bytesToAllocate, int alignment)
        {
            CheckAllocationToLarge(bytesToAllocate);
            var nextByteOffsetAligned = (m_nextByteOffset + alignment - 1) & ~(alignment - 1);
            var nextBlockSize         = nextByteOffsetAligned + bytesToAllocate;

            if (m_blocks.Length == 0 || nextBlockSize > ms_BlockSize)
            {
                CheckExceededBudget();
                // Allocate a fresh block of memory
                m_blocks.Add(AllocatorManager.Allocate(m_handle, sizeof(byte), ms_BlockAlignment, ms_BlockSize));
                m_allocations.Add(0);
                nextByteOffsetAligned = 0;
            }
            var blockIndex = m_blocks.Length - 1;

            var pointer = (byte *)m_blocks[blockIndex] + nextByteOffsetAligned;

            m_nextByteOffset = nextByteOffsetAligned + bytesToAllocate;
            m_allocations.Ptr[blockIndex]++;
            return(pointer);
        }