98 lines
2.2 KiB
C
98 lines
2.2 KiB
C
// vim:fileencoding=utf-8:foldmethod=marker
|
|
|
|
#include "splitmix64.h"
|
|
#include "../../common/aliases/aliases.h"
|
|
#include "../../common/assert/assert.h"
|
|
#include "../../common/platform/platform.h"
|
|
#include <stdlib.h>
|
|
#include <time.h>
|
|
|
|
wp_intern void seedOsGenerator(u64 seed);
|
|
wp_intern u64 genRandomNumber(void);
|
|
|
|
WpSplitmix64State wpPrngSplitmix64Init(void) {
|
|
wp_persist b8 seeded = false;
|
|
if (!seeded) {
|
|
seeded = true;
|
|
seedOsGenerator(0);
|
|
}
|
|
|
|
return (WpSplitmix64State){ .seed = genRandomNumber() };
|
|
}
|
|
|
|
WpSplitmix64State wpPrngSplitmix64InitWithSeed(u64 seed) {
|
|
return (WpSplitmix64State){ .seed = seed };
|
|
}
|
|
|
|
u64 wpPrngSplitmix64(WpSplitmix64State *state) {
|
|
state->seed += 0x9E3779B97f4A7C15;
|
|
|
|
u64 result = state->seed;
|
|
result = (result ^ (result >> 30)) * 0xBF58476D1CE4E5B9;
|
|
result = (result ^ (result >> 27)) * 0x94D049BB133111EB;
|
|
|
|
return result ^ (result >> 31);
|
|
}
|
|
|
|
u64 wpPrngSplitmix64InRange(WpSplitmix64State *state, u64 start, u64 end) {
|
|
return wpPrngSplitmix64(state) % (end - start) + start;
|
|
}
|
|
|
|
u64 wpPrngSplitmix64Choice(WpSplitmix64State *state, u64 available_choices) {
|
|
return wpPrngSplitmix64(state) % available_choices;
|
|
}
|
|
|
|
#if defined(WP_PLATFORM_C) && WP_PLATFORM_C_VERSION >= WP_PLATFORM_C11_VERSION
|
|
#ifdef WP_PLATFORM_POSIX
|
|
wp_intern void seedOsGenerator(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(seed);
|
|
}
|
|
|
|
wp_intern u64 genRandomNumber(void) {
|
|
return lrand48();
|
|
}
|
|
#else
|
|
wp_intern void seedOsGenerator(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(seed);
|
|
}
|
|
|
|
wp_intern u64 genRandomNumber(void) {
|
|
i32 n1 = rand();
|
|
i32 n2 = rand();
|
|
|
|
return (((u64)n1) << 32 | (u64)n2);
|
|
}
|
|
#endif // !WP_PLATFORM_POSIX
|
|
#else
|
|
wp_intern void seedOsGenerator(u64 seed) {
|
|
if (seed == 0) {
|
|
time_t result = time(NULL);
|
|
wpRuntimeAssert(result != (time_t)(-1), "Invalid seed value");
|
|
seed = (u64)result;
|
|
}
|
|
|
|
srand(seed);
|
|
}
|
|
|
|
wp_intern u64 genRandomNumber(void) {
|
|
i32 n1 = rand();
|
|
i32 n2 = rand();
|
|
|
|
return (((u64)n1) << 32 | (u64)n2);
|
|
}
|
|
#endif // !WP_PLATFORM_C
|