/// <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 }