Created
July 27, 2018 15:22
-
-
Save tnayuki/9cc94d5ad297761efd50f4803c30f3b5 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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