[*] Made WELL_NextBytes atomic

This commit is contained in:
Reece Wilson 2021-10-01 18:22:59 +01:00
parent 4703264c57
commit 4f210e15a0

View File

@ -58,11 +58,10 @@ WELLRand WELL_SeedRand64(AuUInt64 seed)
/** /**
* Generates a pseudo-randomly generated long. * Generates a pseudo-randomly generated long.
*/ */
AuUInt32 WELL_NextLong(WELLRand *rand) AuUInt32 WELL_NextLong_Unlocked(WELLRand *rand)
{ {
AuUInt32 a, b, c, d, ret; AuUInt32 a, b, c, d, ret;
rand->lock.Lock();
a = rand->state[rand->index]; a = rand->state[rand->index];
c = rand->state[(rand->index + 13) & 15]; c = rand->state[(rand->index + 13) & 15];
b = a ^ c ^ (a << 16) ^ (c << 15); b = a ^ c ^ (a << 16) ^ (c << 15);
@ -74,6 +73,17 @@ AuUInt32 WELL_NextLong(WELLRand *rand)
a = rand->state[rand->index]; a = rand->state[rand->index];
rand->state[rand->index] = a ^ b ^ d ^ (a << 2) ^ (b << 18) ^ (c << 28); rand->state[rand->index] = a ^ b ^ d ^ (a << 2) ^ (b << 18) ^ (c << 28);
ret = rand->state[rand->index]; ret = rand->state[rand->index];
return ret;
}
/**
* Generates a pseudo-randomly generated long.
*/
AuUInt32 WELL_NextLong(WELLRand *rand)
{
rand->lock.Lock();
AuUInt32 ret = WELL_NextLong_Unlocked(rand);
rand->lock.Unlock(); rand->lock.Unlock();
return ret; return ret;
} }
@ -85,17 +95,21 @@ void WELL_NextBytes(WELLRand *rand, void *in, AuUInt32 length)
i = 0; i = 0;
base = reinterpret_cast<AuUInt8 *>(in); base = reinterpret_cast<AuUInt8 *>(in);
rand->lock.Lock();
for (; i < length; i += 4) for (; i < length; i += 4)
{ {
AuUInt32 rng = WELL_NextLong(rand); AuUInt32 rng = WELL_NextLong_Unlocked(rand);
std::memcpy(base + i, &rng, 4); std::memcpy(base + i, &rng, 4);
} }
if (i > length) if (i > length)
{ {
i -= 4; i -= 4;
AuUInt32 padRng = WELL_NextLong(rand); AuUInt32 padRng = WELL_NextLong_Unlocked(rand);
std::memcpy(base + i, &padRng, length - i); std::memcpy(base + i, &padRng, length - i);
} }
rand->lock.Unlock();
} }