Skip to content

Instantly share code, notes, and snippets.

@tnayuki
Created July 27, 2018 15:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tnayuki/9cc94d5ad297761efd50f4803c30f3b5 to your computer and use it in GitHub Desktop.
Save tnayuki/9cc94d5ad297761efd50f4803c30f3b5 to your computer and use it in GitHub Desktop.
using Unity.Burst;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
using Unity.Jobs.LowLevel.Unsafe;
using System.Threading;
[NativeContainer]
[NativeContainerIsAtomicWriteOnly]
public unsafe struct NativeXorshift64CASFree {
private const int LongsPerCacheLine = JobsUtility.CacheLineSize / sizeof(long);
[NativeDisableUnsafePtrRestriction]
ulong *m_Buffer;
Allocator m_AllocatorLabel;
#if ENABLE_UNITY_COLLECTIONS_CHECKS
AtomicSafetyHandle m_Safety;
[NativeSetClassTypeToNullOnSchedule] DisposeSentinel m_DisposeSentinel;
#endif
[NativeSetThreadIndex] int m_ThreadIndex;
public NativeXorshift64(ulong seed, Allocator label) {
m_AllocatorLabel = label;
m_Buffer = (ulong *)UnsafeUtility.Malloc(JobsUtility.MaxJobThreadCount * sizeof(long) * LongsPerCacheLine, JobsUtility.CacheLineSize, m_AllocatorLabel);
#if ENABLE_UNITY_COLLECTIONS_CHECKS
#if UNITY_2018_3_OR_NEWER
DisposeSentinel.Create(out m_Safety, out m_DisposeSentinel, 0, label);
#else
DisposeSentinel.Create(out m_Safety, out m_DisposeSentinel, 0);
#endif
#endif
m_ThreadIndex = 0;
for (int i = 0; i < JobsUtility.MaxJobThreadCount; i++) {
m_Buffer[i * LongsPerCacheLine] = seed + (ulong)i;
}
}
public void Dispose() {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
#if UNITY_2018_3_OR_NEWER
DisposeSentinel.Dispose(ref m_Safety, ref m_DisposeSentinel);
#else
DisposeSentinel.Dispose(m_Safety, ref m_DisposeSentinel);
#endif
#endif
UnsafeUtility.Free(m_Buffer, m_AllocatorLabel);
}
public ulong Next() {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
AtomicSafetyHandle.CheckWriteAndThrow(m_Safety);
#endif
ulong c = m_Buffer[LongsPerCacheLine * m_ThreadIndex];
c = c ^ (c << 13);
c = c ^ (c >> 17);
c = c ^ (c << 15);
m_Buffer[LongsPerCacheLine * m_ThreadIndex] = c;
return c;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment