説明なし
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

UnsafeScratchAllocator.cs 3.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. using System;
  2. using System.Diagnostics;
  3. namespace Unity.Collections.LowLevel.Unsafe
  4. {
  5. /// <summary>
  6. /// A fixed-size buffer from which you can make allocations.
  7. /// </summary>
  8. /// <remarks>Allocations from a scratch allocator are not individually deallocated.
  9. /// Instead, when you're done using all the allocations from a scratch allocator, you dispose the allocator as a whole.</remarks>
  10. [GenerateTestsForBurstCompatibility]
  11. public unsafe struct UnsafeScratchAllocator
  12. {
  13. void* m_Pointer;
  14. int m_LengthInBytes;
  15. readonly int m_CapacityInBytes;
  16. /// <summary>
  17. /// Initializes and returns an instance of UnsafeScratchAllocator.
  18. /// </summary>
  19. /// <param name="ptr">An existing buffer to use as the allocator's internal buffer.</param>
  20. /// <param name="capacityInBytes">The size in bytes of the internal buffer.</param>
  21. public UnsafeScratchAllocator(void* ptr, int capacityInBytes)
  22. {
  23. m_Pointer = ptr;
  24. m_LengthInBytes = 0;
  25. m_CapacityInBytes = capacityInBytes;
  26. }
  27. [Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS"), Conditional("UNITY_DOTS_DEBUG")]
  28. void CheckAllocationDoesNotExceedCapacity(ulong requestedSize)
  29. {
  30. if (requestedSize > (ulong)m_CapacityInBytes)
  31. throw new ArgumentException($"Cannot allocate more than provided size in UnsafeScratchAllocator. Requested: {requestedSize} Size: {m_LengthInBytes} Capacity: {m_CapacityInBytes}");
  32. }
  33. /// <summary>
  34. /// Returns an allocation from the allocator's internal buffer.
  35. /// </summary>
  36. /// <param name="sizeInBytes">The size of the new allocation.</param>
  37. /// <param name="alignmentInBytes">The alignment of the new allocation.</param>
  38. /// <returns>A pointer to the new allocation.</returns>
  39. /// <exception cref="ArgumentException">Thrown if the new allocation would exceed the capacity of the allocator.</exception>
  40. public void* Allocate(int sizeInBytes, int alignmentInBytes)
  41. {
  42. if (sizeInBytes == 0)
  43. return null;
  44. var alignmentMask = (ulong)(alignmentInBytes - 1);
  45. var end = (ulong)(IntPtr)m_Pointer + (ulong)m_LengthInBytes;
  46. end = (end + alignmentMask) & ~alignmentMask;
  47. var lengthInBytes = (byte*)(IntPtr)end - (byte*)m_Pointer;
  48. lengthInBytes += sizeInBytes;
  49. CheckAllocationDoesNotExceedCapacity((ulong)lengthInBytes);
  50. m_LengthInBytes = (int)lengthInBytes;
  51. return (void*)(IntPtr)end;
  52. }
  53. /// <summary>
  54. /// Returns an allocation from the allocator's internal buffer.
  55. /// </summary>
  56. /// <remarks>The allocation size in bytes is at least `count * sizeof(T)`. The space consumed by the allocation may be a little larger than this size due to alignment.</remarks>
  57. /// <typeparam name="T">The type of element to allocate space for.</typeparam>
  58. /// <param name="count">The number of elements to allocate space for. Defaults to 1.</param>
  59. /// <returns>A pointer to the new allocation.</returns>
  60. /// <exception cref="ArgumentException">Thrown if the new allocation would exceed the capacity of the allocator.</exception>
  61. [GenerateTestsForBurstCompatibility(GenericTypeArguments = new [] { typeof(int) })]
  62. public void* Allocate<T>(int count = 1) where T : unmanaged
  63. {
  64. return Allocate(UnsafeUtility.SizeOf<T>() * count, UnsafeUtility.AlignOf<T>());
  65. }
  66. }
  67. }