A game about forced loneliness, made by TACStudios
at master 192 lines 6.1 kB view raw
1using NUnit.Framework; 2using System.Collections.Generic; 3using Unity.Jobs; 4using Unity.Burst; 5using Unity.Collections; 6using Unity.Collections.Tests; 7using Assert = FastAssert; 8 9internal class UnsafeQueueTests_InJobs : CollectionsTestCommonBase 10{ 11 struct NestedContainerJob : IJob 12 { 13 public UnsafeQueue<UnsafeQueue<int>> nestedContainer; 14 15 public void Execute() 16 { 17 nestedContainer.Clear(); 18 } 19 } 20 21 [BurstCompile(CompileSynchronously = true)] 22 struct ConcurrentEnqueue : IJobParallelFor 23 { 24 public UnsafeQueue<int>.ParallelWriter queue; 25 26 [NativeDisableParallelForRestriction] 27 public NativeArray<int> result; 28 29 public int StartIndex; 30 31 public void Execute(int index) 32 { 33 index += StartIndex; 34 result[index] = 1; 35 queue.Enqueue(index); 36 } 37 } 38 39 [Test] 40 public void Enqueue() 41 { 42 const int queueSize = 100 * 1024; 43 var queue = new UnsafeQueue<int>(CommonRwdAllocator.Handle); 44 var writeStatus = CollectionHelper.CreateNativeArray<int>(queueSize, CommonRwdAllocator.Handle); 45 46 var enqueueJob = new ConcurrentEnqueue() 47 { 48 queue = queue.AsParallelWriter(), 49 result = writeStatus, 50 StartIndex = 0, 51 }; 52 53 var enqueue = enqueueJob.Schedule(queueSize, 1); 54 enqueue.Complete(); 55 56 Assert.AreEqual(queueSize, queue.Count, "Job enqueued the wrong number of values"); 57 var allValues = new NativeParallelHashSet<int>(queueSize, Allocator.Persistent); 58 for (int i = 0; i < queueSize; ++i) 59 { 60 Assert.AreEqual(1, writeStatus[i], "Job failed to enqueue value"); 61 int enqueued = queue.Dequeue(); 62 Assert.IsTrue(enqueued >= 0 && enqueued < queueSize, "Job enqueued invalid value"); 63 Assert.IsTrue(allValues.Add(enqueued), "Job enqueued same value multiple times"); 64 } 65 66 var disposeJob = queue.Dispose(enqueue); 67 disposeJob.Complete(); 68 69 writeStatus.Dispose(); 70 allValues.Dispose(); 71 } 72 73 [BurstCompile(CompileSynchronously = true)] 74 struct EnqueueDequeueJob : IJob 75 { 76 public UnsafeQueue<int> queue; 77 [ReadOnly] public NativeArray<int> arr; 78 public int val; 79 80 public void Execute() 81 { 82 for (int i = 0; i < 10000; ++i) 83 { 84 queue.Enqueue(0); 85 val += arr[queue.Dequeue()]; 86 } 87 } 88 } 89 90 [Test] 91 public void EnqueueDequeueMultipleQueuesInMultipleJobs() 92 { 93 var handles = new NativeArray<JobHandle>(4, Allocator.Temp); 94 for (int i = 0; i < 10; ++i) 95 { 96 var q1 = new UnsafeQueue<int>(CommonRwdAllocator.Handle); 97 var q2 = new UnsafeQueue<int>(CommonRwdAllocator.Handle); 98 var q3 = new UnsafeQueue<int>(CommonRwdAllocator.Handle); 99 var q4 = new UnsafeQueue<int>(CommonRwdAllocator.Handle); 100 var rangeCheck = CollectionHelper.CreateNativeArray<int>(1, CommonRwdAllocator.Handle); 101 var j1 = new EnqueueDequeueJob {queue = q1, arr = rangeCheck, val = 0}; 102 var j2 = new EnqueueDequeueJob {queue = q2, arr = rangeCheck, val = 0}; 103 var j3 = new EnqueueDequeueJob {queue = q3, arr = rangeCheck, val = 0}; 104 var j4 = new EnqueueDequeueJob {queue = q4, arr = rangeCheck, val = 0}; 105 handles[0] = j1.Schedule(); 106 handles[1] = j2.Schedule(); 107 handles[2] = j3.Schedule(); 108 handles[3] = j4.Schedule(); 109 JobHandle.ScheduleBatchedJobs(); 110 111 JobHandle.CombineDependencies(handles).Complete(); 112 113 q1.Dispose(); 114 q2.Dispose(); 115 q3.Dispose(); 116 q4.Dispose(); 117 rangeCheck.Dispose(); 118 } 119 handles.Dispose(); 120 } 121 122 struct EnqueueJob : IJobParallelFor 123 { 124 public UnsafeQueue<int>.ParallelWriter Queue; 125 public void Execute(int index) 126 { 127 Queue.Enqueue(index); 128 } 129 } 130 131 [Test] 132 public void ToArray_WorksFromJobs() 133 { 134 using (var queue = new UnsafeQueue<int>(CommonRwdAllocator.Handle)) 135 { 136 new EnqueueJob 137 { 138 Queue = queue.AsParallelWriter() 139 }.Schedule(100, 10).Complete(); 140 Assert.AreEqual(100, queue.Count); 141 using (var arr = queue.ToArray(Allocator.Temp)) 142 { 143 Assert.AreEqual(100, arr.Length); 144 arr.Sort(); 145 for (int i = 0; i < arr.Length; i++) 146 Assert.AreEqual(i, arr[i]); 147 } 148 } 149 } 150 151 [Test] 152 public void UnsafeQueue_ParallelWriter() 153 { 154 const int queueSize = 100 * 1024; 155 var queue = new UnsafeQueue<int>(CommonRwdAllocator.Handle); 156 var writeStatus = CollectionHelper.CreateNativeArray<int>(queueSize, CommonRwdAllocator.Handle); 157 158 var jobHandle = new ConcurrentEnqueue() 159 { 160 queue = queue.AsParallelWriter(), 161 result = writeStatus, 162 StartIndex = 0, 163 164 }.Schedule(queueSize / 2, 1); 165 166 jobHandle = new ConcurrentEnqueue() 167 { 168 queue = queue.AsParallelWriter(), 169 result = writeStatus, 170 StartIndex = queueSize / 2, 171 172 }.Schedule(queueSize / 2, 1, jobHandle); 173 174 jobHandle.Complete(); 175 176 Assert.AreEqual(queueSize, queue.Count, "Job enqueued the wrong number of values"); 177 var allValues = new NativeParallelHashSet<int>(queueSize, Allocator.Persistent); 178 for (int i = 0; i < queueSize; ++i) 179 { 180 Assert.AreEqual(1, writeStatus[i], "Job failed to enqueue value"); 181 int enqueued = queue.Dequeue(); 182 Assert.IsTrue(enqueued >= 0 && enqueued < queueSize, "Job enqueued invalid value"); 183 Assert.IsTrue(allValues.Add(enqueued), "Job enqueued same value multiple times"); 184 } 185 186 var disposeJob = queue.Dispose(jobHandle); 187 disposeJob.Complete(); 188 189 writeStatus.Dispose(); 190 allValues.Dispose(); 191 } 192}