private static void Allocate(int length, Allocator allocator, out NativeArray <T> array) { long num = (long)UnsafeUtility.SizeOf <T>() * (long)length; if (allocator <= Allocator.None) { throw new ArgumentException("Allocator must be Temp, TempJob or Persistent", "allocator"); } if (length < 0) { throw new ArgumentOutOfRangeException("length", "Length must be >= 0"); } if (!UnsafeUtility.IsBlittable <T>()) { throw new ArgumentException(string.Format("{0} used in NativeArray<{0}> must be blittable", typeof(T))); } if (num > 2147483647L) { throw new ArgumentOutOfRangeException("length", string.Format("Length * sizeof(T) cannot exceed {0} bytes", 2147483647)); } array.m_Buffer = UnsafeUtility.Malloc((ulong)num, UnsafeUtility.AlignOf <T>(), allocator); array.m_Length = length; array.m_AllocatorLabel = allocator; array.m_MinIndex = 0; array.m_MaxIndex = length - 1; DisposeSentinel.Create(array.m_Buffer, allocator, out array.m_Safety, out array.m_DisposeSentinel, 1, null); }
public NativeConcurrentIntArray(int size, Allocator label) { // This check is redundant since we always use an int which is blittable. // It is here as an example of how to check for type correctness for generic types. #if ENABLE_UNITY_COLLECTIONS_CHECKS if (!UnsafeUtility.IsBlittable <int>()) { throw new ArgumentException(string.Format("{0} used in NativeQueue<{0}> must be blittable", typeof(int))); } #endif m_AllocatorLabel = label; // Allocate native memory for a single integer m_Counter = (int *)UnsafeUtility.Malloc(UnsafeUtility.SizeOf <int>() * size, 4, label); // Create a dispose sentinel to track memory leaks. This also creates the AtomicSafetyHandle #if ENABLE_UNITY_COLLECTIONS_CHECKS #if UNITY_2018_3_OR_NEWER DisposeSentinel.Create(out m_Safety, out m_DisposeSentinel, 0, label); #else DisposeSentinel.Create(out m_Safety, out m_DisposeSentinel, 0); #endif #endif // Initialize the count to 0 to avoid uninitialized data for (int i = 0; i < size; ++i) { *(m_Counter + i) = 0; } }
public NativePerThreadCounter(Allocator label) { // This check is redundant since we always use an int which is blittable. // It is here as an example of how to check for type correctness for generic types. #if ENABLE_UNITY_COLLECTIONS_CHECKS if (!UnsafeUtility.IsBlittable <int>()) { throw new ArgumentException(string.Format("{0} used in NativeQueue<{0}> must be blittable", typeof(int))); } #endif m_AllocatorLabel = label; // One full cache line (integers per cacheline * size of integer) for each potential worker index, JobsUtility.MaxJobThreadCount m_Counter = (int *)UnsafeUtility.Malloc(UnsafeUtility.SizeOf <int>() * IntsPerCacheLine * JobsUtility.MaxJobThreadCount, 4, label); // Create a dispose sentinel to track memory leaks. This also creates the AtomicSafetyHandle #if ENABLE_UNITY_COLLECTIONS_CHECKS #if UNITY_2018_3_OR_NEWER DisposeSentinel.Create(out m_Safety, out m_DisposeSentinel, 0, label); #else DisposeSentinel.Create(out m_Safety, out m_DisposeSentinel, 0); #endif #endif // Initialize the count to 0 to avoid uninitialized data Count = 0; }
HashedVertices(int vertexCapacity, int chainedIndicesCapacity, Allocator allocator, int disposeSentinelStackDepth) { #if ENABLE_UNITY_COLLECTIONS_CHECKS // Native allocation is only valid for Temp, Job and Persistent. CheckAllocator(allocator); CheckArgPositive(chainedIndicesCapacity); DisposeSentinel.Create(out m_Safety, out m_DisposeSentinel, disposeSentinelStackDepth, allocator); #if UNITY_2020_1_OR_NEWER if (s_staticSafetyId.Data == 0) { CreateStaticSafetyId(); } AtomicSafetyHandle.SetStaticSafetyId(ref m_Safety, s_staticSafetyId.Data); #endif #endif #if ENABLE_UNITY_COLLECTIONS_CHECKS DisposeSentinel.Create(out m_Safety, out m_DisposeSentinel, 0, allocator); #endif m_AllocatorLabel = allocator; var hashTableMemSize = (ushort)(kHashTableSize + 1) * UnsafeUtility.SizeOf <ushort>(); m_HashTable = UnsafeUtility.Malloc(hashTableMemSize, UnsafeUtility.AlignOf <ushort>(), m_AllocatorLabel); UnsafeUtility.MemClear(m_HashTable, hashTableMemSize); m_Vertices = UnsafeList.Create(UnsafeUtility.SizeOf <float3>(), UnsafeUtility.AlignOf <float3>(), vertexCapacity, allocator); m_ChainedIndices = UnsafeList.Create(UnsafeUtility.SizeOf <ushort>(), UnsafeUtility.AlignOf <ushort>(), chainedIndicesCapacity, allocator); #if ENABLE_UNITY_COLLECTIONS_CHECKS AtomicSafetyHandle.SetBumpSecondaryVersionOnScheduleWrite(m_Safety, true); #endif }
/// <summary> /// Initializes a new instance of the <see cref="NativeMinHeap"/> struct. /// </summary> /// <param name="capacity"> The capacity of the min heap. </param> /// <param name="allocator"> The allocator. </param> /// <exception cref="ArgumentOutOfRangeException"> Thrown if allocator not set, capacity is negative or the size > maximum integer value. </exception> public NativeMinHeap(int capacity, Allocator allocator) { var size = (long)UnsafeUtility.SizeOf <MinHeapNode>() * capacity; if (allocator <= Allocator.None) { throw new ArgumentException("Allocator must be Temp, TempJob or Persistent", nameof(allocator)); } if (capacity < 0) { throw new ArgumentOutOfRangeException(nameof(capacity), "Length must be >= 0"); } if (size > int.MaxValue) { throw new ArgumentOutOfRangeException( nameof(capacity), $"Length * sizeof(T) cannot exceed {int.MaxValue} bytes"); } this.buffer = UnsafeUtility.Malloc(size, UnsafeUtility.AlignOf <MinHeapNode>(), allocator); this.capacity = capacity; this.allocator = allocator; this.head = -1; this.length = 0; #if ENABLE_UNITY_COLLECTIONS_CHECKS DisposeSentinel.Create(out this.m_Safety, out this.m_DisposeSentinel, 1, allocator); #endif }
public KnnContainer(NativeArray <float3> points, bool buildNow, Allocator allocator) { int nodeCountEstimate = 4 * (int)math.ceil(points.Length / (float)c_maxPointsPerLeafNode + 1) + 1; Points = points; // Both arrays are filled in as we go, so start with uninitialized mem m_nodes = new NativeList <KdNode>(nodeCountEstimate, allocator); // Dumb way to create an int* essentially.. m_permutation = new NativeArray <int>(points.Length, allocator, NativeArrayOptions.UninitializedMemory); m_rootNodeIndex = new NativeArray <int>(new[] { -1 }, allocator); m_buildQueue = new NativeQueue <int>(allocator); #if ENABLE_UNITY_COLLECTIONS_CHECKS if (allocator <= Allocator.None) { throw new ArgumentException("Allocator must be Temp, TempJob or Persistent", nameof(allocator)); } if (points.Length <= 0) { throw new ArgumentOutOfRangeException(nameof(points), "Input points length must be >= 0"); } DisposeSentinel.Create(out m_Safety, out m_DisposeSentinel, 0, allocator); #endif if (buildNow) { var rebuild = new KnnRebuildJob(this); rebuild.Schedule().Complete(); } }
/// <summary> /// Allocate memory and set the initial value /// </summary> /// /// <param name="allocator"> /// Allocator to allocate and deallocate with. Must be valid. /// </param> /// /// <param name="initialValue"> /// Initial value of the allocated memory /// </param> public NativeIntPtr(Allocator allocator, int initialValue = 0) { // Require a valid allocator if (allocator <= Allocator.None) { throw new ArgumentException( "Allocator must be Temp, TempJob or Persistent", "allocator"); } // Allocate the memory for the value m_Buffer = (int *)UnsafeUtility.Malloc( sizeof(int), UnsafeUtility.AlignOf <int>(), allocator); // Store the allocator to use when deallocating m_AllocatorLabel = allocator; // Create the dispose sentinel #if ENABLE_UNITY_COLLECTIONS_CHECKS #if UNITY_2018_3_OR_NEWER DisposeSentinel.Create(out m_Safety, out m_DisposeSentinel, 0, allocator); #else DisposeSentinel.Create(out m_Safety, out m_DisposeSentinel, 0); #endif #endif // Set the initial value *m_Buffer = initialValue; }
private NativeRoutines(int initialCapacity, Allocator allocator, int disposeSentinelStackDepth) { var totalSize = (long)sizeof(T) * initialCapacity; #if ENABLE_UNITY_COLLECTIONS_CHECKS // Native allocation is only valid for Temp, Job and Persistent. if (allocator <= Allocator.None) { throw new ArgumentException("Allocator must be Temp, TempJob or Persistent", nameof(allocator)); } if (totalSize > int.MaxValue) { throw new ArgumentOutOfRangeException($"Capacity has exceeded {int.MaxValue.ToString()} bytes"); } DisposeSentinel.Create(out m_Safety, out m_DisposeSentinel, disposeSentinelStackDepth, allocator); #endif m_ListData = UnsafeList.Create(UnsafeUtility.SizeOf <T>(), UnsafeUtility.AlignOf <T>(), initialCapacity, allocator); m_AllocatorLabel = allocator; #if UNITY_2019_3_OR_NEWER && ENABLE_UNITY_COLLECTIONS_CHECKS AtomicSafetyHandle.SetBumpSecondaryVersionOnScheduleWrite(m_Safety, true); #endif }
public NativeValue(Allocator allocator, Op valueOperator = default(Op)) { // Safety checks #if ENABLE_UNITY_COLLECTIONS_CHECKS if (allocator <= Allocator.None) { throw new ArgumentException("Allocator must be Temp, TempJob or Persistent", nameof(allocator)); } if (!UnsafeUtility.IsBlittable <T>()) { throw new ArgumentException(string.Format("{0} used in NativeValue<{0}, {1}> must be blittable", typeof(T), typeof(Op))); } if (UnsafeUtility.SizeOf <T>() > JobsUtility.CacheLineSize) { throw new ArgumentException(string.Format("{0} used in NativeValue<{0}, {1}> had a size of {2} which is greater than the maximum size of {3}", typeof(T), typeof(Op), UnsafeUtility.SizeOf <T>(), JobsUtility.CacheLineSize)); } if (UnsafeUtility.SizeOf <Op>() > 1) { throw new ArgumentException(string.Format("{0} used in NativeValue<{1}, {0}> had a size of {2} which is greater than 1. Access to {0} is not thread safe and can therefor not contain any member variables", typeof(Op), typeof(T), UnsafeUtility.SizeOf <Op>(), JobsUtility.CacheLineSize)); } DisposeSentinel.Create(out m_Safety, out m_DisposeSentinel, 0, allocator); #endif // Allocate a cache line for each worker thread. m_Buffer = UnsafeUtility.Malloc(JobsUtility.CacheLineSize * JobsUtility.MaxJobThreadCount, JobsUtility.CacheLineSize, allocator); m_AllocatorLabel = allocator; m_Operator = valueOperator; Value = m_Operator.getIdentity(); }
static void AllocateBlock(out BlockStream stream, uint uniqueBlockStreamId, Allocator allocator) { #if ENABLE_UNITY_COLLECTIONS_CHECKS if (allocator <= Allocator.None) { throw new ArgumentException("Allocator must be Temp, TempJob or Persistent", "allocator"); } #endif int blockCount = JobsUtility.MaxJobThreadCount; int allocationSize = sizeof(BlockStreamData) + sizeof(Block *) * blockCount; byte *buffer = (byte *)UnsafeUtility.Malloc(allocationSize, 16, allocator); UnsafeUtility.MemClear(buffer, allocationSize); var block = (BlockStreamData *)buffer; stream.m_Block = block; stream.m_AllocatorLabel = allocator; stream.m_UniqueBlockStreamId = uniqueBlockStreamId; block->Allocator = allocator; block->BlockCount = blockCount; block->Blocks = (Block **)(buffer + sizeof(BlockStreamData)); block->Ranges = null; block->RangeCount = 0; #if ENABLE_UNITY_COLLECTIONS_CHECKS DisposeSentinel.Create(out stream.m_Safety, out stream.m_DisposeSentinel, 0, allocator); #endif }
internal MeshDataArray(Mesh mesh) { // error checking if (mesh == null) { throw new ArgumentNullException(nameof(mesh), "Mesh is null"); } if (!mesh.canAccess) { throw new InvalidOperationException($"Not allowed to access vertex data on mesh '{mesh.name}' (isReadable is false; Read/Write must be enabled in import settings)"); } m_Length = 1; var totalSize = UnsafeUtility.SizeOf <IntPtr>(); m_Ptrs = (IntPtr *)UnsafeUtility.Malloc(totalSize, UnsafeUtility.AlignOf <IntPtr>(), Allocator.Persistent); AcquireReadOnlyMeshData(mesh, m_Ptrs); m_MinIndex = 0; m_MaxIndex = m_Length - 1; DisposeSentinel.Create(out m_Safety, out m_DisposeSentinel, 1, Allocator.TempJob); // secondary version with write disabled makes the NativeArrays returned // by MeshData actually be read-only AtomicSafetyHandle.SetAllowSecondaryVersionWriting(m_Safety, false); AtomicSafetyHandle.UseSecondaryVersion(ref m_Safety); }
/// <summary> /// Creates a new, empty priority queue with the specified capacity. /// </summary> /// <param name="capacity">The maximum number of nodes that will be stored in the queue.</param> /// <param name="allocator">Allocator</param> public BinaryHeap(int capacity, Allocator allocator) { _mAllocatorLabel = allocator; _capacity = capacity; long size = (long)UnsafeUtility.SizeOf <T>() * capacity; if (allocator <= Allocator.None) { throw new ArgumentException("Allocator must be Temp, TempJob or Persistent", nameof(allocator)); } if (capacity < 0) { throw new ArgumentOutOfRangeException(nameof(capacity), "Length must be >= 0"); } if (size > int.MaxValue) { throw new ArgumentOutOfRangeException(nameof(capacity), $"Length * sizeof(T) cannot exceed {(object) int.MaxValue} bytes"); } _data = UnsafeUtility.Malloc(size, UnsafeUtility.AlignOf <T>(), allocator); _priorities = new K[capacity]; Count = 0; #if ENABLE_UNITY_COLLECTIONS_CHECKS DisposeSentinel.Create(out _mSafety, out _mDisposeSentinel, 1, allocator); #endif }
public NativeArrayFullSOA(int length, Allocator label, int stackDepth) { #if ENABLE_UNITY_COLLECTIONS_CHECKS if (!UnsafeUtility.IsBlittable <T>()) { throw new ArgumentException($"{typeof(T)} is not blittable"); } #endif if (!ms_CachedLayout.IsCreated) { ms_CachedLayout = new StructLayoutData4(typeof(T)); } m_Base = (byte *)UnsafeUtility.Malloc(4 * length * ms_CachedLayout.FieldCount, StructLayoutData4.ChunkSizeBytes, label); m_Length = length; m_Allocator = label; #if ENABLE_UNITY_COLLECTIONS_CHECKS #if UNITY_2018_3_OR_NEWER DisposeSentinel.Create(out m_Safety, out m_DisposeSentinel, stackDepth, label); #else DisposeSentinel.Create(out m_Safety, out m_DisposeSentinel, stackDepth); #endif #endif }
private static void Allocate(int length0, int length1, Allocator allocator, out NativeArray2D <T> array) { RequireValidAllocator(allocator); if (!UnsafeUtility.IsUnmanaged <T>()) { throw new InvalidOperationException("Only unmanaged types are supported."); } int length = length0 * length1; if (length <= 0) { throw new InvalidOperationException("Total number of elements must be greater than zero."); } array = new NativeArray2D <T> { m_Buffer = UnsafeUtility.Malloc(length * UnsafeUtility.SizeOf <T>(), UnsafeUtility.AlignOf <T>(), allocator), m_Length0 = length0, m_Length1 = length1, m_Length = length1 * length0, m_AllocatorLabel = allocator }; #if ENABLE_UNITY_COLLECTIONS_CHECKS DisposeSentinel.Create(out array.m_Safety, out array.m_DisposeSentinel, 1, allocator); #endif }
private static void Allocate(int capacity, Allocator allocator, out NativeMinHeap nativeMinHeap) { var size = (long)UnsafeUtility.SizeOf <PathNode>() * capacity; if (allocator <= Allocator.None) { throw new ArgumentException("Allocator must be Temp, TempJob or Persistent", nameof(allocator)); } if (capacity < 0) { throw new ArgumentOutOfRangeException(nameof(capacity), "Length must be >= 0"); } if (size > int.MaxValue) { throw new ArgumentOutOfRangeException(nameof(capacity), $"Length * sizeof(T) cannot exceed {(object)int.MaxValue} bytes"); } nativeMinHeap.m_Buffer = UnsafeUtility.Malloc(size, UnsafeUtility.AlignOf <PathNode>(), allocator); nativeMinHeap.m_capacity = capacity; nativeMinHeap.m_AllocatorLabel = allocator; nativeMinHeap.m_MinIndex = 0; nativeMinHeap.m_MaxIndex = capacity - 1; nativeMinHeap.m_head = -1; nativeMinHeap.m_length = 0; #if ENABLE_UNITY_COLLECTIONS_CHECKS DisposeSentinel.Create(out nativeMinHeap.m_Safety, out nativeMinHeap.m_DisposeSentinel, 1, allocator); #endif }
public NativeSummedFloat3(Allocator allocator) { // Safety checks #if ENABLE_UNITY_COLLECTIONS_CHECKS if (allocator <= Allocator.None) { throw new ArgumentException("Allocator must be Temp, TempJob or Persistent", nameof(allocator)); } // There are other checks you might want to perform when working with generic containers. /* * if (!UnsafeUtility.IsBlittable<T>()) * throw new ArgumentException(string.Format("{0} used in NativeValue<{0}> must be blittable", typeof(T))); * * if (UnsafeUtility.SizeOf<T>() > JobsUtility.CacheLineSize) * throw new ArgumentException(string.Format("{0} used in NativeValue<{0}> had a size of {1} which is greater than the maximum size of {2}", typeof(T), UnsafeUtility.SizeOf<T>(), JobsUtility.CacheLineSize)); */ DisposeSentinel.Create(out m_Safety, out m_DisposeSentinel, 0, allocator); #endif // Allocate a cache line for each worker thread. m_Buffer = UnsafeUtility.Malloc(JobsUtility.CacheLineSize * JobsUtility.MaxJobThreadCount, JobsUtility.CacheLineSize, allocator); m_AllocatorLabel = allocator; Value = float3.zero; }
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 }
unsafe private NativeList(int capacity, Allocator i_label, int stackDepth) { #if ENABLE_UNITY_COLLECTIONS_CHECKS if (!UnsafeUtility.IsBlittable <T>()) { throw new ArgumentException(string.Format("{0} used in NativeList<{0}> must be blittable", typeof(T))); } #endif NativeListData *data = (NativeListData *)UnsafeUtility.Malloc(sizeof(NativeListData), UnsafeUtility.AlignOf <NativeListData>(), i_label); int elementSize = UnsafeUtility.SizeOf <T> (); //@TODO: Find out why this is needed? capacity = Math.Max(1, capacity); data->list = UnsafeUtility.Malloc(capacity * elementSize, UnsafeUtility.AlignOf <T>(), i_label); data->length = 0; data->capacity = capacity; m_Buffer = data; m_AllocatorLabel = i_label; #if ENABLE_UNITY_COLLECTIONS_CHECKS DisposeSentinel.Create(out m_Safety, out m_DisposeSentinel, stackDepth); #endif }
NativeList(int initialCapacity, Allocator allocator, int disposeSentinelStackDepth) { var totalSize = UnsafeUtility.SizeOf <T>() * (long)initialCapacity; #if ENABLE_UNITY_COLLECTIONS_CHECKS // Native allocation is only valid for Temp, Job and Persistent. if (allocator <= Allocator.None) { throw new ArgumentException("Allocator must be Temp, TempJob or Persistent", nameof(allocator)); } if (initialCapacity < 0) { throw new ArgumentOutOfRangeException(nameof(initialCapacity), "Capacity must be >= 0"); } CollectionHelper.CheckIsUnmanaged <T>(); // Make sure we cannot allocate more than int.MaxValue (2,147,483,647 bytes) // because the underlying UnsafeUtility.Malloc is expecting a int. // TODO: change UnsafeUtility.Malloc to accept a UIntPtr length instead to match C++ API if (totalSize > int.MaxValue) { throw new ArgumentOutOfRangeException(nameof(initialCapacity), $"Capacity * sizeof(T) cannot exceed {int.MaxValue} bytes"); } DisposeSentinel.Create(out m_Safety, out m_DisposeSentinel, disposeSentinelStackDepth, allocator); #endif m_ListData = UnsafeList.Create(UnsafeUtility.SizeOf <T>(), UnsafeUtility.AlignOf <T>(), initialCapacity, allocator); m_DeprecatedAllocator = allocator; #if ENABLE_UNITY_COLLECTIONS_CHECKS AtomicSafetyHandle.SetBumpSecondaryVersionOnScheduleWrite(m_Safety, true); #endif }
public unsafe ComponentTypeHandleArray(int length, Allocator allocator) { long size = ElementSize * (long)length; if (allocator <= Allocator.None) { throw new ArgumentException("Allocator must be Temp, TempJob or Persistent", nameof(allocator)); } if (length < 0) { throw new ArgumentOutOfRangeException(nameof(length), "Length must be >= 0"); } if (size > (long)int.MaxValue) { throw new ArgumentOutOfRangeException(nameof(length), $"Length * sizeof(DynamicComponentTypeHandle) cannot exceed {int.MaxValue.ToString()} bytes"); } m_Buffer = UnsafeUtility.Malloc(size, Alignment, allocator); m_Length = length; m_AllocatorLabel = allocator; #if ENABLE_UNITY_COLLECTIONS_CHECKS DisposeSentinel.Create(out m_Safety, out m_DisposeSentinel, 1, allocator); #endif }
public NativeBinaryHeap(int initialCapacity, Allocator allocator) { // Insist on a minimum capacity initialCapacity = ceilpow2(initialCapacity); initialCapacity = max(initialCapacity, 4); var sizeOf = SizeOf <T>(); var totalSize = sizeOf * (long)initialCapacity; #if ENABLE_UNITY_COLLECTIONS_CHECKS if (allocator <= Allocator.None) { throw new ArgumentException( "Allocator must be Temp, TempJob or Persistent", nameof(allocator)); } if (totalSize > int.MaxValue) { throw new ArgumentOutOfRangeException(nameof(initialCapacity), $"Capacity * sizeof(T) cannot exceed {int.MaxValue} bytes"); } DisposeSentinel.Create(out this.safety, out this.disposeSentinel, 0, allocator); #endif var alignOf = AlignOf <T>(); this.binaryHeapData = UnsafeBinaryHeap.Create(sizeOf, alignOf, initialCapacity, allocator); }
static void Allocate(int length, Allocator allocator, out NativeArray <T> array) { var totalSize = UnsafeUtility.SizeOf <T>() * (long)length; // Native allocation is only valid for Temp, Job and Persistent. if (allocator <= Allocator.None) { throw new ArgumentException("Allocator must be Temp, TempJob or Persistent", nameof(allocator)); } if (length < 0) { throw new ArgumentOutOfRangeException(nameof(length), "Length must be >= 0"); } IsUnmanagedAndThrow(); // Make sure we cannot allocate more than int.MaxValue (2,147,483,647 bytes) // because the underlying UnsafeUtility.Malloc is expecting a int. // TODO: change UnsafeUtility.Malloc to accept a UIntPtr length instead to match C++ API if (totalSize > int.MaxValue) { throw new ArgumentOutOfRangeException(nameof(length), $"Length * sizeof(T) cannot exceed {int.MaxValue} bytes"); } array = default(NativeArray <T>); array.m_Buffer = UnsafeUtility.Malloc(totalSize, UnsafeUtility.AlignOf <T>(), allocator); array.m_Length = length; array.m_AllocatorLabel = allocator; array.m_MinIndex = 0; array.m_MaxIndex = length - 1; DisposeSentinel.Create(out array.m_Safety, out array.m_DisposeSentinel, 1, allocator); }
/// <summary> /// Constructs a new result with an initial value. You must specify the Allocator /// type to use to allocate the memory used by this Result container. /// /// You can optionally specify an instance of the Op type to use to combine results /// into the final single result. You only need to specify an instance if the op will /// contain specific instance data that is important to performing its operation. /// /// For operations that need no context, such as addition, no operation needs to be /// specified, as the result will use the default instance automatically based on the /// Op type argument. /// </summary> public Result(Allocator allocator, Op op = default(Op)) { #if ENABLE_UNITY_COLLECTIONS_CHECKS if (!UnsafeUtility.IsBlittable <T>()) { throw new ArgumentException($"{typeof(T)} used in Result<{typeof(T)}, {typeof(Op)}> must be blittable"); } if (UnsafeUtility.SizeOf <T>() > JobsUtility.CacheLineSize) { throw new ArgumentException($"{typeof(T)} used in Result<{typeof(T)}, { typeof(Op)}> had a size of {UnsafeUtility.SizeOf<T>()} which is greater than the maximum size of {JobsUtility.CacheLineSize}"); } DisposeSentinel.Create(out m_Safety, out m_DisposeSentinel, 1, allocator); #endif unsafe { m_Buffer = (IntPtr)UnsafeUtility.Malloc(JobsUtility.CacheLineSize * JobsUtility.MaxJobThreadCount, JobsUtility.CacheLineSize, allocator); } m_AllocatorLabel = allocator; m_Op = op; Reset(); }
public SpatialHash(Bounds worldBounds, float3 cellSize, int startSize, Allocator label) { #if ENABLE_UNITY_COLLECTIONS_CHECKS DisposeSentinel.Create(out _safety, out _disposeSentinel, 0, label); #endif _allocatorLabel = label; _data = (SpatialHashData *)UnsafeUtility.Malloc(sizeof(SpatialHashData), UnsafeUtility.AlignOf <SpatialHashData>(), label); _data->WorldBounds = worldBounds; _data->WorldBoundsMin = worldBounds.Min; _data->CellSize = cellSize; _data->CellCount = worldBounds.GetCellCount(cellSize); _data->RayCastBound = new Bounds(); _data->HasHit = false; _data->Counter = 0; _data->RayOrigin = float3.zero; _data->RayDirection = float3.zero; _buckets = new NativeMultiHashMap <uint, int>(startSize, label); _itemIDToBounds = new NativeHashMap <int, Bounds>(startSize >> 1, label); _itemIDToItem = new NativeHashMap <int, T>(startSize >> 1, label); _helpMoveHashMapOld = new NativeHashMap <int3, byte>(128, _allocatorLabel); _helpMoveHashMapNew = new NativeHashMap <int3, byte>(128, _allocatorLabel); _voxelRay = new VoxelRay <SpatialHash <T> >(); _rayHitValue = 0; }
/// <summary> /// Allocate memory and set the initial value /// </summary> /// /// <param name="allocator"> /// Allocator to allocate and deallocate with. Must be valid. /// </param> /// /// <param name="initialValue"> /// Initial value of the allocated memory /// </param> public NativePerJobThreadLongPtr( Allocator allocator, long initialValue = 0) { // Require a valid allocator if (allocator <= Allocator.None) { throw new ArgumentException( "Allocator must be Temp, TempJob or Persistent", "allocator"); } // Allocate the memory for the values m_Buffer = (long *)UnsafeUtility.Malloc( JobsUtility.CacheLineSize * JobsUtility.MaxJobThreadCount, UnsafeUtility.AlignOf <long>(), allocator); // Store the allocator to use when deallocating m_AllocatorLabel = allocator; // Create the dispose sentinel #if ENABLE_UNITY_COLLECTIONS_CHECKS #if UNITY_2018_3_OR_NEWER DisposeSentinel.Create(out m_Safety, out m_DisposeSentinel, 0, allocator); #else DisposeSentinel.Create(out m_Safety, out m_DisposeSentinel, 0); #endif #endif // Set the initial value Value = initialValue; }
internal MeshDataArray(Mesh[] meshes, int meshesCount) { // error checking if (meshes.Length < meshesCount) { throw new InvalidOperationException($"Meshes array size ({meshes.Length}) is smaller than meshes count ({meshesCount})"); } for (int i = 0; i < meshesCount; ++i) { Mesh m = meshes[i]; if (m == null) { throw new ArgumentNullException(nameof(meshes), $"Mesh at index {i} is null"); } if (!m.canAccess) { throw new InvalidOperationException($"Not allowed to access vertex data on mesh '{m.name}' at array index {i} (isReadable is false; Read/Write must be enabled in import settings)"); } } m_Length = meshesCount; var totalSize = UnsafeUtility.SizeOf <IntPtr>() * meshesCount; m_Ptrs = (IntPtr *)UnsafeUtility.Malloc(totalSize, UnsafeUtility.AlignOf <IntPtr>(), Allocator.Persistent); AcquireReadOnlyMeshDatas(meshes, m_Ptrs, meshesCount); m_MinIndex = 0; m_MaxIndex = m_Length - 1; DisposeSentinel.Create(out m_Safety, out m_DisposeSentinel, 1, Allocator.TempJob); // secondary version with write disabled makes the NativeArrays returned // by MeshData actually be read-only AtomicSafetyHandle.SetAllowSecondaryVersionWriting(m_Safety, false); AtomicSafetyHandle.UseSecondaryVersion(ref m_Safety); }
NativeHashMap(int capacity, Allocator allocator, int disposeSentinelStackDepth) { m_HashMapData = new UnsafeHashMap <TKey, TValue>(capacity, allocator, disposeSentinelStackDepth); #if ENABLE_UNITY_COLLECTIONS_CHECKS DisposeSentinel.Create(out m_Safety, out m_DisposeSentinel, disposeSentinelStackDepth, allocator); #endif }
public NativeHandle(TObj obj, Allocator label) { m_AllocatorLabel = label; m_Handle = GCHandle.Alloc(obj, GCHandleType.Pinned); #if ENABLE_UNITY_COLLECTIONS_CHECKS DisposeSentinel.Create(out m_Safety, out m_DisposeSentinel, 0, label); #endif }
public OctreeReader(BoundsOctree <VolumetricAssetOctreeNode> octree) { // Create a dispose sentinel to track memory leaks. This also creates the AtomicSafetyHandle #if ENABLE_UNITY_COLLECTIONS_CHECKS DisposeSentinel.Create(out m_Safety, out m_DisposeSentinel, 0, Allocator.TempJob); #endif // Initialize the reference _octree = octree; }
static void AllocateBlock(out NativeStream stream, Allocator allocator) { CheckAllocator(allocator); UnsafeStream.AllocateBlock(out stream.m_Stream, allocator); #if ENABLE_UNITY_COLLECTIONS_CHECKS DisposeSentinel.Create(out stream.m_Safety, out stream.m_DisposeSentinel, 0, allocator); #endif }