212 lines
6.5 KiB
C#
212 lines
6.5 KiB
C#
|
using NUnit.Framework;
|
||
|
using System.Collections.Generic;
|
||
|
using Unity.Jobs;
|
||
|
using Unity.Burst;
|
||
|
using Unity.Collections;
|
||
|
using Unity.Collections.Tests;
|
||
|
using Assert = FastAssert;
|
||
|
using System;
|
||
|
|
||
|
internal class NativeQueueTests_InJobs : CollectionsTestCommonBase
|
||
|
{
|
||
|
struct NestedContainerJob : IJob
|
||
|
{
|
||
|
public NativeQueue<NativeQueue<int>> nestedContainer;
|
||
|
|
||
|
public void Execute()
|
||
|
{
|
||
|
nestedContainer.Clear();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
[TestRequiresCollectionChecks]
|
||
|
public void NativeQueue_NestedJob_Error()
|
||
|
{
|
||
|
var container = new NativeQueue<NativeQueue<int>>(CommonRwdAllocator.Handle);
|
||
|
|
||
|
var nestedJob = new NestedContainerJob
|
||
|
{
|
||
|
nestedContainer = container
|
||
|
};
|
||
|
|
||
|
JobHandle job = default;
|
||
|
Assert.Throws<System.InvalidOperationException>(() => { job = nestedJob.Schedule(); });
|
||
|
job.Complete();
|
||
|
|
||
|
container.Dispose();
|
||
|
}
|
||
|
|
||
|
[BurstCompile(CompileSynchronously = true)]
|
||
|
struct ConcurrentEnqueue : IJobParallelFor
|
||
|
{
|
||
|
public NativeQueue<int>.ParallelWriter queue;
|
||
|
|
||
|
[NativeDisableParallelForRestriction]
|
||
|
public NativeArray<int> result;
|
||
|
|
||
|
public int StartIndex;
|
||
|
|
||
|
public void Execute(int index)
|
||
|
{
|
||
|
index += StartIndex;
|
||
|
result[index] = 1;
|
||
|
queue.Enqueue(index);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void Enqueue()
|
||
|
{
|
||
|
const int queueSize = 100 * 1024;
|
||
|
var queue = new NativeQueue<int>(CommonRwdAllocator.Handle);
|
||
|
var writeStatus = CollectionHelper.CreateNativeArray<int>(queueSize, CommonRwdAllocator.Handle);
|
||
|
|
||
|
var enqueueJob = new ConcurrentEnqueue()
|
||
|
{
|
||
|
queue = queue.AsParallelWriter(),
|
||
|
result = writeStatus,
|
||
|
StartIndex = 0,
|
||
|
};
|
||
|
|
||
|
var enqueue = enqueueJob.Schedule(queueSize, 1);
|
||
|
enqueue.Complete();
|
||
|
|
||
|
Assert.AreEqual(queueSize, queue.Count, "Job enqueued the wrong number of values");
|
||
|
var allValues = new NativeParallelHashSet<int>(queueSize, Allocator.Persistent);
|
||
|
for (int i = 0; i < queueSize; ++i)
|
||
|
{
|
||
|
Assert.AreEqual(1, writeStatus[i], "Job failed to enqueue value");
|
||
|
int enqueued = queue.Dequeue();
|
||
|
Assert.IsTrue(enqueued >= 0 && enqueued < queueSize, "Job enqueued invalid value");
|
||
|
Assert.IsTrue(allValues.Add(enqueued), "Job enqueued same value multiple times");
|
||
|
}
|
||
|
|
||
|
var disposeJob = queue.Dispose(enqueue);
|
||
|
disposeJob.Complete();
|
||
|
|
||
|
writeStatus.Dispose();
|
||
|
allValues.Dispose();
|
||
|
}
|
||
|
|
||
|
[BurstCompile(CompileSynchronously = true)]
|
||
|
struct EnqueueDequeueJob : IJob
|
||
|
{
|
||
|
public NativeQueue<int> queue;
|
||
|
[ReadOnly] public NativeArray<int> arr;
|
||
|
public int val;
|
||
|
|
||
|
public void Execute()
|
||
|
{
|
||
|
for (int i = 0; i < 10000; ++i)
|
||
|
{
|
||
|
queue.Enqueue(0);
|
||
|
val += arr[queue.Dequeue()];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void EnqueueDequeueMultipleQueuesInMultipleJobs()
|
||
|
{
|
||
|
var handles = new NativeArray<JobHandle>(4, Allocator.Temp);
|
||
|
for (int i = 0; i < 10; ++i)
|
||
|
{
|
||
|
var q1 = new NativeQueue<int>(CommonRwdAllocator.Handle);
|
||
|
var q2 = new NativeQueue<int>(CommonRwdAllocator.Handle);
|
||
|
var q3 = new NativeQueue<int>(CommonRwdAllocator.Handle);
|
||
|
var q4 = new NativeQueue<int>(CommonRwdAllocator.Handle);
|
||
|
var rangeCheck = CollectionHelper.CreateNativeArray<int>(1, CommonRwdAllocator.Handle);
|
||
|
var j1 = new EnqueueDequeueJob {queue = q1, arr = rangeCheck, val = 0};
|
||
|
var j2 = new EnqueueDequeueJob {queue = q2, arr = rangeCheck, val = 0};
|
||
|
var j3 = new EnqueueDequeueJob {queue = q3, arr = rangeCheck, val = 0};
|
||
|
var j4 = new EnqueueDequeueJob {queue = q4, arr = rangeCheck, val = 0};
|
||
|
handles[0] = j1.Schedule();
|
||
|
handles[1] = j2.Schedule();
|
||
|
handles[2] = j3.Schedule();
|
||
|
handles[3] = j4.Schedule();
|
||
|
JobHandle.ScheduleBatchedJobs();
|
||
|
|
||
|
JobHandle.CombineDependencies(handles).Complete();
|
||
|
|
||
|
q1.Dispose();
|
||
|
q2.Dispose();
|
||
|
q3.Dispose();
|
||
|
q4.Dispose();
|
||
|
rangeCheck.Dispose();
|
||
|
}
|
||
|
handles.Dispose();
|
||
|
}
|
||
|
|
||
|
struct EnqueueJob : IJobParallelFor
|
||
|
{
|
||
|
public NativeQueue<int>.ParallelWriter Queue;
|
||
|
public void Execute(int index)
|
||
|
{
|
||
|
Queue.Enqueue(index);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void ToArray_WorksFromJobs()
|
||
|
{
|
||
|
using (var queue = new NativeQueue<int>(CommonRwdAllocator.Handle))
|
||
|
{
|
||
|
new EnqueueJob
|
||
|
{
|
||
|
Queue = queue.AsParallelWriter()
|
||
|
}.Schedule(100, 10).Complete();
|
||
|
Assert.AreEqual(100, queue.Count);
|
||
|
using (var arr = queue.ToArray(Allocator.Temp))
|
||
|
{
|
||
|
Assert.AreEqual(100, arr.Length);
|
||
|
arr.Sort();
|
||
|
for (int i = 0; i < arr.Length; i++)
|
||
|
Assert.AreEqual(i, arr[i]);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void NativeQueue_ParallelWriter()
|
||
|
{
|
||
|
const int queueSize = 100 * 1024;
|
||
|
var queue = new NativeQueue<int>(CommonRwdAllocator.Handle);
|
||
|
var writeStatus = CollectionHelper.CreateNativeArray<int>(queueSize, CommonRwdAllocator.Handle);
|
||
|
|
||
|
var jobHandle = new ConcurrentEnqueue()
|
||
|
{
|
||
|
queue = queue.AsParallelWriter(),
|
||
|
result = writeStatus,
|
||
|
StartIndex = 0,
|
||
|
|
||
|
}.Schedule(queueSize / 2, 1);
|
||
|
|
||
|
jobHandle = new ConcurrentEnqueue()
|
||
|
{
|
||
|
queue = queue.AsParallelWriter(),
|
||
|
result = writeStatus,
|
||
|
StartIndex = queueSize / 2,
|
||
|
|
||
|
}.Schedule(queueSize / 2, 1, jobHandle);
|
||
|
|
||
|
jobHandle.Complete();
|
||
|
|
||
|
Assert.AreEqual(queueSize, queue.Count, "Job enqueued the wrong number of values");
|
||
|
var allValues = new NativeParallelHashSet<int>(queueSize, Allocator.Persistent);
|
||
|
for (int i = 0; i < queueSize; ++i)
|
||
|
{
|
||
|
Assert.AreEqual(1, writeStatus[i], "Job failed to enqueue value");
|
||
|
int enqueued = queue.Dequeue();
|
||
|
Assert.IsTrue(enqueued >= 0 && enqueued < queueSize, "Job enqueued invalid value");
|
||
|
Assert.IsTrue(allValues.Add(enqueued), "Job enqueued same value multiple times");
|
||
|
}
|
||
|
|
||
|
var disposeJob = queue.Dispose(jobHandle);
|
||
|
disposeJob.Complete();
|
||
|
|
||
|
writeStatus.Dispose();
|
||
|
allValues.Dispose();
|
||
|
}
|
||
|
}
|