暂无描述
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

RewindableAllocatorTests.cs 6.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. using System;
  2. using NUnit.Framework;
  3. using Unity.Collections;
  4. using Unity.Collections.LowLevel.Unsafe;
  5. using Unity.Collections.Tests;
  6. #if !UNITY_DOTSRUNTIME && ENABLE_UNITY_COLLECTIONS_CHECKS
  7. internal class RewindableAllocatorTests
  8. {
  9. AllocatorHelper<RewindableAllocator> m_AllocatorHelper;
  10. protected ref RewindableAllocator RwdAllocator => ref m_AllocatorHelper.Allocator;
  11. [SetUp]
  12. public void Setup()
  13. {
  14. m_AllocatorHelper = new AllocatorHelper<RewindableAllocator>(Allocator.Persistent);
  15. m_AllocatorHelper.Allocator.Initialize(128 * 1024, true);
  16. }
  17. [TearDown]
  18. public void TearDown()
  19. {
  20. m_AllocatorHelper.Allocator.Dispose();
  21. m_AllocatorHelper.Dispose();
  22. }
  23. [Test]
  24. public unsafe void RewindTestVersionOverflow()
  25. {
  26. // Check allocator version overflow
  27. for (int i = 0; i < 65536 + 100; i++)
  28. {
  29. var container = RwdAllocator.AllocateNativeList<byte>(RwdAllocator.InitialSizeInBytes / 1000);
  30. container.Resize(1, NativeArrayOptions.ClearMemory);
  31. container[0] = 0xFE;
  32. RwdAllocator.Rewind();
  33. CollectionHelper.CheckAllocator(RwdAllocator.ToAllocator);
  34. }
  35. }
  36. #if UNITY_2022_3_OR_NEWER
  37. [Test]
  38. public unsafe void NativeArrayCustomAllocatorExceptionWorks()
  39. {
  40. NativeArray<int> array = default;
  41. Assert.Throws<ArgumentException>(() =>
  42. {
  43. array = new NativeArray<int>(2, RwdAllocator.ToAllocator);
  44. });
  45. }
  46. #endif
  47. public unsafe void RewindInvalidatesNativeList()
  48. {
  49. var container = RwdAllocator.AllocateNativeList<byte>(RwdAllocator.InitialSizeInBytes / 1000);
  50. container.Resize(1, NativeArrayOptions.ClearMemory);
  51. container[0] = 0xFE;
  52. RwdAllocator.Rewind();
  53. Assert.Throws<ObjectDisposedException>(() =>
  54. {
  55. container[0] = 0xEF;
  56. });
  57. }
  58. [Test]
  59. public unsafe void RewindInvalidatesNativeArray()
  60. {
  61. var container = RwdAllocator.AllocateNativeArray<byte>(RwdAllocator.InitialSizeInBytes / 1000);
  62. container[0] = 0xFE;
  63. RwdAllocator.Rewind();
  64. Assert.Throws<ObjectDisposedException>(() =>
  65. {
  66. container[0] = 0xEF;
  67. });
  68. }
  69. [Test]
  70. public unsafe void NativeListCanBeCreatedViaMemberFunction()
  71. {
  72. var container = RwdAllocator.AllocateNativeList<byte>(RwdAllocator.InitialSizeInBytes / 1000);
  73. container.Resize(1, NativeArrayOptions.ClearMemory);
  74. container[0] = 0xFE;
  75. }
  76. [Test]
  77. public unsafe void NativeListCanBeDisposed()
  78. {
  79. var container = RwdAllocator.AllocateNativeList<byte>(RwdAllocator.InitialSizeInBytes / 1000);
  80. container.Resize(1, NativeArrayOptions.ClearMemory);
  81. container[0] = 0xFE;
  82. container.Dispose();
  83. RwdAllocator.Rewind();
  84. }
  85. [Test]
  86. public void NativeArrayCanBeDisposed()
  87. {
  88. var container = RwdAllocator.AllocateNativeArray<byte>(RwdAllocator.InitialSizeInBytes / 1000);
  89. container[0] = 0xFE;
  90. container.Dispose();
  91. RwdAllocator.Rewind();
  92. }
  93. [Test]
  94. public void NumberOfBlocksIsTemporarilyStable()
  95. {
  96. RwdAllocator.AllocateNativeList<byte>(RwdAllocator.InitialSizeInBytes * 10);
  97. var blocksBefore = RwdAllocator.BlocksAllocated;
  98. RwdAllocator.Rewind();
  99. var blocksAfter = RwdAllocator.BlocksAllocated;
  100. Assert.AreEqual(blocksAfter, blocksBefore);
  101. }
  102. [Test]
  103. public void NumberOfBlocksEventuallyDrops()
  104. {
  105. RwdAllocator.AllocateNativeList<byte>(RwdAllocator.InitialSizeInBytes * 10);
  106. var blocksBefore = RwdAllocator.BlocksAllocated;
  107. RwdAllocator.Rewind();
  108. RwdAllocator.Rewind();
  109. var blocksAfter = RwdAllocator.BlocksAllocated;
  110. Assert.IsTrue(blocksAfter < blocksBefore);
  111. }
  112. [Test]
  113. public void PossibleToAllocateGigabytes()
  114. {
  115. const int giga = 1024 * 1024 * 1024;
  116. var container0 = RwdAllocator.AllocateNativeList<byte>(giga);
  117. var container1 = RwdAllocator.AllocateNativeList<byte>(giga);
  118. var container2 = RwdAllocator.AllocateNativeList<byte>(giga);
  119. container0.Resize(1, NativeArrayOptions.ClearMemory);
  120. container1.Resize(1, NativeArrayOptions.ClearMemory);
  121. container2.Resize(1, NativeArrayOptions.ClearMemory);
  122. container0[0] = 0;
  123. container1[0] = 1;
  124. container2[0] = 2;
  125. Assert.AreEqual((byte)0, container0[0]);
  126. Assert.AreEqual((byte)1, container1[0]);
  127. Assert.AreEqual((byte)2, container2[0]);
  128. }
  129. [Test]
  130. public void ExhaustsFirstBlockBeforeAllocatingMore()
  131. {
  132. for (var i = 0; i < 50; ++i)
  133. {
  134. RwdAllocator.AllocateNativeList<byte>(RwdAllocator.InitialSizeInBytes / 100);
  135. Assert.AreEqual(1, RwdAllocator.BlocksAllocated);
  136. }
  137. RwdAllocator.AllocateNativeList<byte>(RwdAllocator.InitialSizeInBytes);
  138. Assert.AreEqual(2, RwdAllocator.BlocksAllocated);
  139. }
  140. unsafe struct ListProvider
  141. {
  142. NativeList<byte> m_Bytes;
  143. public ListProvider(AllocatorManager.AllocatorHandle allocatorHandle) => m_Bytes = new NativeList<byte>(allocatorHandle);
  144. public void Append<T>(ref T data) where T : unmanaged =>
  145. m_Bytes.AddRange(UnsafeUtility.AddressOf(ref data), UnsafeUtility.SizeOf<T>());
  146. }
  147. static void TriggerBug(AllocatorManager.AllocatorHandle allocatorHandle, NativeArray<byte> data)
  148. {
  149. var listProvider = new ListProvider(allocatorHandle);
  150. var datum = 0u;
  151. listProvider.Append(ref datum); // 'data' is now invalid after call to AtomicSafetyHandle.CheckWriteAndBumpSecondaryVersion(m_Safety);
  152. Assert.That(data[0], Is.EqualTo(0));
  153. }
  154. [Test]
  155. public void AddRange_WhenCalledOnStructMember_DoesNotInvalidateUnrelatedListHigherOnCallStack()
  156. {
  157. AllocatorManager.AllocatorHandle allocatorHandle = RwdAllocator.Handle;
  158. var unrelatedList = new NativeList<byte>(allocatorHandle) { 0, 0 };
  159. Assert.That(unrelatedList.Length, Is.EqualTo(2));
  160. Assert.That(unrelatedList[0], Is.EqualTo(0));
  161. TriggerBug(allocatorHandle, unrelatedList);
  162. }
  163. }
  164. #endif