示例#1
0
            /// <summary>
            /// Allocates an index which corresponds to a buffer.
            /// </summary>
            /// <returns>Allocated index. If allocation fails, returned index is negative.</returns>
            /// <exception cref="InvalidOperationException">Thrown when allocator is exhausted or when buffer cannot be committed.</exception>
            public int Allocate()
            {
                if (FreeList.IsEmpty)
                {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                    throw new InvalidOperationException("Cannot allocate, allocator is exhausted.");
#else
                    return(-1);
#endif
                }

                int lastFreeListIndex = FreeList.Length - 1;
                int index             = FreeList.Ptr[lastFreeListIndex];
                BaselibErrorState errorState;
                var range = new VMRange((IntPtr)this[index], (uint)BufferSizeInBytes, VirtualMemoryUtility.DefaultPageSizeInBytes);
                VirtualMemoryUtility.CommitMemory(range, out errorState);

                if (!errorState.Success)
                {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                    throw new InvalidOperationException($"Failed to commit address range {range}.");
#else
                    return(-1);
#endif
                }

                FreeList.RemoveAtSwapBack(lastFreeListIndex);

                return(index);
            }
        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);
        }
        public void Free(void *pointer)
        {
            if (pointer == null)
            {
                return;
            }
            var blocks = m_allocations.Length; // how many blocks have we allocated?

            for (var i = blocks - 1; i >= 0; --i)
            {
                var block = (byte *)m_blocks[i];                        // get a pointer to the block.
                if (pointer >= block && pointer < block + ms_BlockSize) // is the pointer we want to free in this block?
                {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                    if (m_allocations.Ptr[i] <= 0) // if that block has no allocations, we can't proceed
                    {
                        throw new ArgumentException($"Cannot free this pointer from BlockAllocator: no more allocations to free in its block.");
                    }
#endif
                    if (--m_allocations.Ptr[i] == 0) // if this was the last allocation in the block,
                    {
                        if (i == blocks - 1)         // if it's the last block,
                        {
                            m_nextByteOffset = 0;    // just forget that we allocated anything from it, but keep it for later allocations
                        }
                        else
                        {
                            AllocatorManager.Free(m_handle, (void *)m_blocks[i]); // delete the block
                            m_blocks.RemoveAtSwapBack(i);                         // and forget we ever saw it
                            m_allocations.RemoveAtSwapBack(i);                    // and your dog toto, too
                        }
                    }
                    return;
                }
            }
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            throw new ArgumentException($"Cannot free this pointer from BlockAllocator: can't be found in any block.");
#endif
        }