A game about forced loneliness, made by TACStudios
at master 272 lines 10 kB view raw
1using System; 2using NUnit.Framework; 3using Unity.Burst; 4using Unity.Collections; 5using Unity.Mathematics; 6using Unity.Collections.LowLevel.Unsafe; 7using Unity.Jobs; 8 9internal class ConcurrentMaskTests 10{ 11 internal struct Test 12 { 13 internal long value; 14 internal int bits; 15 internal long expectedModified; 16 internal int offset; 17 internal bool expectedWorked; 18 internal Test(ulong uValue, ulong uExpectedModified, bool w) 19 { 20 this = default; 21 value = (long)uValue; 22 expectedModified = (long)uExpectedModified; 23 expectedWorked = w; 24 } 25 internal Test(ulong uValue, int bits, ulong uExpectedModified, bool w) 26 { 27 this = default; 28 value = (long)uValue; 29 this.bits = bits; 30 expectedModified = (long)uExpectedModified; 31 expectedWorked = w; 32 } 33 internal Test(ulong uValue, ulong uExpectedModified, int offset, bool w) 34 { 35 this = default; 36 value = (long)uValue; 37 expectedModified = (long)uExpectedModified; 38 this.offset = offset; 39 expectedWorked = w; 40 } 41 internal Test(ulong uValue, int bits, ulong uExpectedModified, int offset, bool w) 42 { 43 value = (long)uValue; 44 this.bits = bits; 45 expectedModified = (long)uExpectedModified; 46 this.offset = offset; 47 expectedWorked = w; 48 } 49 } 50 51 [Test] 52 public void AllocatesOneBitFromLong() 53 { 54 foreach(var test in new Test[] { 55 new Test(0x0000000000000000UL,0x0000000000000001UL, true), 56 new Test(0x0000000000000001UL,0x0000000000000003UL, true), 57 new Test(0x00000000000000FFUL,0x00000000000001FFUL, true), 58 new Test(0x0000000000000100UL,0x0000000000000101UL, true), 59 new Test(0x7FFFFFFFFFFFFFFFUL,0xFFFFFFFFFFFFFFFFUL, true), 60 new Test(0x8000000000000000UL,0x8000000000000001UL, true), 61 }) { 62 long value = test.value; 63 long expectedModified = test.expectedModified; 64 long modified = value; 65 var worked = ConcurrentMask.TryAllocate(ref modified, out int _, 1); 66 Assert.AreEqual(expectedModified, modified); 67 Assert.AreEqual(test.expectedWorked, ConcurrentMask.Succeeded(worked)); 68 } 69 } 70 71 [Test] 72 public void FailsToAllocateOneBitFromLong() 73 { 74 foreach(var test in new Test[] { 75 new Test(0xFFFFFFFFFFFFFFFFUL,0xFFFFFFFFFFFFFFFFUL, false) 76 }) { 77 long value = test.value; 78 long expectedModified = test.expectedModified; 79 long modified = value; 80 var worked = ConcurrentMask.TryAllocate(ref modified, out int _, 1); 81 Assert.AreEqual(expectedModified, modified); 82 Assert.AreEqual(test.expectedWorked, ConcurrentMask.Succeeded(worked)); 83 } 84 } 85 86 [Test] 87 public void AllocatesMultipleBitsFromLong() 88 { 89 foreach(var test in new Test[] { 90 new Test(0x0000000000000000UL, 64,0xFFFFFFFFFFFFFFFFUL, true), 91 new Test(0x0000000000000000UL, 2,0x0000000000000003UL, true), 92 new Test(0x0000000000000001UL,63,0xFFFFFFFFFFFFFFFFUL, true), 93 new Test(0x00000000000000FFUL,8, 0x000000000000FFFFUL, true), 94 new Test(0x00000000000FF0FFUL,8, 0x000000000FFFF0FFUL, true), 95 }) { 96 long value = test.value; 97 long expectedModified = test.expectedModified; 98 long modified = value; 99 var worked = ConcurrentMask.TryAllocate(ref modified, out int _, test.bits); 100 Assert.AreEqual(expectedModified, modified); 101 Assert.AreEqual(test.expectedWorked, ConcurrentMask.Succeeded(worked)); 102 } 103 } 104 105 [Test] 106 public void FailsToAllocateMultipleBitsFromLong() 107 { 108 foreach(var test in new Test[] { 109 new Test(0x0000000000000000UL, 65,0x0000000000000000UL, false), 110 new Test(0x0000000000000001UL,64,0x0000000000000001UL, false), 111 new Test(0xFF000000000000FFUL,49, 0xFF000000000000FFUL, false), 112 }) { 113 long value = test.value; 114 long expectedModified = test.expectedModified; 115 long modified = value; 116 var worked = ConcurrentMask.TryAllocate(ref modified, out int _, test.bits); 117 Assert.AreEqual(expectedModified, modified); 118 Assert.AreEqual(test.expectedWorked, ConcurrentMask.Succeeded(worked)); 119 } 120 } 121 122 [Test] 123 public void FreesOneBitFromLong() 124 { 125 foreach(var test in new Test[] { 126 new Test(0x0000000000000000UL,0x0000000000000001UL, 0, true), 127 new Test(0x0000000000000001UL,0x0000000000000003UL, 1, true), 128 new Test(0x00000000000000FFUL,0x00000000000001FFUL, 8, true), 129 new Test(0x0000000000000100UL,0x0000000000000101UL, 0, true), 130 new Test(0x7FFFFFFFFFFFFFFFUL,0xFFFFFFFFFFFFFFFFUL, 63, true), 131 new Test(0x8000000000000000UL,0x8000000000000001UL, 0, true), 132 }) { 133 long expectedModified = (long)test.value; 134 long modified = (long)test.expectedModified; 135 var worked = ConcurrentMask.TryFree(ref modified, test.offset, 1); 136 Assert.AreEqual(expectedModified, modified); 137 Assert.AreEqual(test.expectedWorked, ConcurrentMask.Succeeded(worked)); 138 } 139 } 140 141 [Test] 142 public void FreesMultipleBitsFromLong() 143 { 144 foreach(var test in new Test[] { 145 new Test(0x0000000000000000UL, 64,0xFFFFFFFFFFFFFFFFUL, 0, true), 146 new Test(0x0000000000000000UL, 2,0x0000000000000003UL, 0, true), 147 new Test(0x0000000000000001UL,63,0xFFFFFFFFFFFFFFFFUL, 1, true), 148 new Test(0x00000000000000FFUL,8, 0x000000000000FFFFUL, 8, true), 149 new Test(0x00000000000FF0FFUL,8, 0x000000000FFFF0FFUL, 20, true), 150 }) { 151 long expectedModified = test.value; 152 long modified = test.expectedModified; 153 var worked = ConcurrentMask.TryFree(ref modified, test.offset, test.bits); 154 Assert.AreEqual(expectedModified, modified); 155 Assert.AreEqual(test.expectedWorked, ConcurrentMask.Succeeded(worked)); 156 } 157 } 158 159 [Test] 160 public void AllocatesOneBitFromArray() 161 { 162 var storage = new NativeList<long>(3, Allocator.Persistent); 163 storage.Length = 3; 164 for(var i = 0; i < 64; ++i) 165 { 166 var worked = ConcurrentMask.TryAllocate(ref storage, out int offset, 1); 167 Assert.AreEqual(true, ConcurrentMask.Succeeded(worked)); 168 Assert.AreEqual(i, offset); 169 } 170 Assert.AreEqual(-1L, storage[0]); 171 Assert.AreEqual(0L, storage[1]); 172 Assert.AreEqual(0L, storage[2]); 173 for(var i = 0; i < 64; ++i) 174 { 175 var worked = ConcurrentMask.TryAllocate(ref storage, out int offset, 1); 176 Assert.AreEqual(true, ConcurrentMask.Succeeded(worked)); 177 Assert.AreEqual(64+i, offset); 178 } 179 Assert.AreEqual(-1L, storage[0]); 180 Assert.AreEqual(-1L, storage[1]); 181 Assert.AreEqual(0L, storage[2]); 182 storage.Dispose(); 183 } 184 185 [Test] 186 public void AllocatesMultipleBitsFromArray() 187 { 188 var storage = new NativeList<long>(3, Allocator.Persistent); 189 storage.Length = 3; 190 for(var i = 0; i < 3; ++i) 191 { 192 var worked = ConcurrentMask.TryAllocate(ref storage, out int offset, 33); 193 Assert.AreEqual(true, ConcurrentMask.Succeeded(worked)); 194 Assert.AreEqual(i * 64, offset); 195 } 196 { 197 var worked = ConcurrentMask.TryAllocate(ref storage, out int offset, 33); 198 Assert.AreEqual(false, ConcurrentMask.Succeeded(worked)); 199 } 200 storage.Dispose(); 201 } 202 203 [Test] 204 public void FreesOneBitFromArray() 205 { 206 var storage = new NativeList<long>(3, Allocator.Persistent); 207 storage.Length = 3; 208 ConcurrentMask.TryAllocate(ref storage, out int _, 64); 209 ConcurrentMask.TryAllocate(ref storage, out int _, 64); 210 ConcurrentMask.TryAllocate(ref storage, out int _, 64); 211 for(var i = 0; i < 64 * 3; ++i) 212 { 213 var worked = ConcurrentMask.TryFree(ref storage, i, 1); 214 Assert.AreEqual(true, ConcurrentMask.Succeeded(worked)); 215 } 216 Assert.AreEqual(0L, storage[0]); 217 Assert.AreEqual(0L, storage[1]); 218 Assert.AreEqual(0L, storage[2]); 219 storage.Dispose(); 220 } 221 222 [Test] 223 public void FreesMultipleBitsFromArray() 224 { 225 var storage = new NativeList<long>(3, Allocator.Persistent); 226 storage.Length = 3; 227 ConcurrentMask.TryAllocate(ref storage, out int _, 64); 228 ConcurrentMask.TryAllocate(ref storage, out int _, 64); 229 ConcurrentMask.TryAllocate(ref storage, out int _, 64); 230 for(var i = 0; i < 3; ++i) 231 { 232 var worked = ConcurrentMask.TryFree(ref storage, i * 64 + 1, 63); 233 Assert.AreEqual(true, ConcurrentMask.Succeeded(worked)); 234 } 235 Assert.AreEqual(1L, storage[0]); 236 Assert.AreEqual(1L, storage[1]); 237 Assert.AreEqual(1L, storage[2]); 238 storage.Dispose(); 239 } 240 241 [BurstCompile(CompileSynchronously = true)] 242 struct AllocateJob : IJobParallelFor 243 { 244 [NativeDisableContainerSafetyRestriction] public NativeList<long> m_storage; 245 public void Execute(int index) 246 { 247 ConcurrentMask.TryAllocate(ref m_storage, out int _, 1); 248 } 249 } 250 251 [Test] 252 public void AllocatesFromJob() 253 { 254 const int kLengthInWords = 10; 255 const int kLengthInBits = kLengthInWords * 64; 256 var storage = new NativeList<long>(kLengthInWords, Allocator.Persistent); 257 storage.Length = kLengthInWords; 258 259 for (int i = 0; i < kLengthInWords; ++i) 260 Assert.AreEqual(0L, storage[i]); 261 262 var allocateJob = new AllocateJob(); 263 allocateJob.m_storage = storage; 264 allocateJob.Schedule(kLengthInBits, 1).Complete(); 265 266 for (int i = 0; i < kLengthInWords; ++i) 267 Assert.AreEqual(~0L, storage[i]); 268 269 storage.Dispose(); 270 } 271 272}