|
|
|
@@ -4,6 +4,7 @@
|
|
|
|
|
#include "../../common/aliases/aliases.h"
|
|
|
|
|
#include "../../common/assert/assert.h"
|
|
|
|
|
#include "../../common/platform/platform.h"
|
|
|
|
|
#include "../../common/misc/misc_utils.h"
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <time.h>
|
|
|
|
|
|
|
|
|
@@ -12,16 +13,19 @@ struct SplitMix64State {
|
|
|
|
|
u64 seed;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
wp_intern u64 rol64(u64 x, u64 bits);
|
|
|
|
|
wp_intern u64 split_mix_64(SplitMix64State *state);
|
|
|
|
|
wp_intern void seed_os_generator(void);
|
|
|
|
|
wp_intern void seed_os_generator(u64 seed);
|
|
|
|
|
wp_intern u64 generate_random_number(void);
|
|
|
|
|
|
|
|
|
|
WpXor256State wpPrngXorshiftInit(void) {
|
|
|
|
|
return wpPrngXorshiftInitWithSeed(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
WpXor256State wpPrngXorshiftInitWithSeed(u64 seed) {
|
|
|
|
|
wp_persist b8 seeded = false;
|
|
|
|
|
if (!seeded) {
|
|
|
|
|
seeded = true;
|
|
|
|
|
seed_os_generator();
|
|
|
|
|
seed_os_generator(seed);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SplitMix64State sm64 = {.seed = generate_random_number()};
|
|
|
|
@@ -46,7 +50,7 @@ u64 wpPrngXorshift256(WpXor256State *state) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
u64 wpPrngXorshift256ss(WpXor256State *state) {
|
|
|
|
|
const u64 result = rol64(state->z * 5, 7) * 9;
|
|
|
|
|
const u64 result = wpMiscUtilsRotl64(state->z * 5, 7) * 9;
|
|
|
|
|
const u64 t = state->z << 17;
|
|
|
|
|
|
|
|
|
|
state->y ^= state->w;
|
|
|
|
@@ -55,7 +59,7 @@ u64 wpPrngXorshift256ss(WpXor256State *state) {
|
|
|
|
|
state->w ^= state->x;
|
|
|
|
|
|
|
|
|
|
state->y ^= t;
|
|
|
|
|
state->x = rol64(state->x, 45);
|
|
|
|
|
state->x = wpMiscUtilsRotl64(state->x, 45);
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
@@ -70,15 +74,11 @@ u64 wpPrngXorshift256p(WpXor256State *state) {
|
|
|
|
|
state->w ^= state->x;
|
|
|
|
|
|
|
|
|
|
state->y ^= t;
|
|
|
|
|
state->x = rol64(state->x, 45);
|
|
|
|
|
state->x = wpMiscUtilsRotl64(state->x, 45);
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wp_intern u64 rol64(u64 x, u64 bits) {
|
|
|
|
|
return (x << bits) | (x >> (64 - bits));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wp_intern u64 split_mix_64(SplitMix64State *state) {
|
|
|
|
|
state->seed += 0x9E3779B97f4A7C15;
|
|
|
|
|
|
|
|
|
@@ -91,24 +91,30 @@ wp_intern u64 split_mix_64(SplitMix64State *state) {
|
|
|
|
|
|
|
|
|
|
#if defined(WP_PLATFORM_C) && WP_PLATFORM_C_VERSION >= WP_PLATFORM_C11_VERSION
|
|
|
|
|
#ifdef WP_PLATFORM_POSIX
|
|
|
|
|
wp_intern void seed_os_generator(void) {
|
|
|
|
|
wp_intern void seed_os_generator(u64 seed) {
|
|
|
|
|
if (seed == 0) {
|
|
|
|
|
struct timespec ts = {0};
|
|
|
|
|
int result = clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
|
|
|
|
|
wpRuntimeAssert(result == 0, "Invalid seed value");
|
|
|
|
|
seed = (u64)ts.tv_nsec;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
srand48(ts.tv_nsec);
|
|
|
|
|
srand48(seed);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wp_intern u64 generate_random_number(void) {
|
|
|
|
|
return lrand48();
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
wp_intern void seed_os_generator(void) {
|
|
|
|
|
wp_intern void seed_os_generator(u64 seed) {
|
|
|
|
|
if (seed == 0) {
|
|
|
|
|
struct timespec ts = {0};
|
|
|
|
|
int result = timespec_get(&ts, TIME_UTC);
|
|
|
|
|
wpRuntimeAssert(result != 0, "Invalid seed value");
|
|
|
|
|
seed = (u64)ts.tv_nsec;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
srand(ts.tv_nsec);
|
|
|
|
|
srand(seed);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wp_intern u64 generate_random_number(void) {
|
|
|
|
@@ -119,11 +125,14 @@ wp_intern u64 generate_random_number(void) {
|
|
|
|
|
}
|
|
|
|
|
#endif // !WP_PLATFORM_POSIX
|
|
|
|
|
#else
|
|
|
|
|
wp_intern void seed_os_generator(void) {
|
|
|
|
|
wp_intern void seed_os_generator(u64 seed) {
|
|
|
|
|
if (seed == 0) {
|
|
|
|
|
time_t result = time(NULL);
|
|
|
|
|
wpRuntimeAssert(result != (time_t)(-1), "Invalid seed value");
|
|
|
|
|
seed = (u64)result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
srand(result);
|
|
|
|
|
srand(seed);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wp_intern u64 generate_random_number(void) {
|
|
|
|
|