From bf675ada612c514ad1a18a0a89d804ea265dca8b Mon Sep 17 00:00:00 2001 From: Andrew Belt Date: Fri, 11 Nov 2022 06:26:14 -0500 Subject: [PATCH] Make simple random state global instead of thread-local. --- include/random.hpp | 8 +++----- src/random.cpp | 21 ++++++++------------- 2 files changed, 11 insertions(+), 18 deletions(-) diff --git a/include/random.hpp b/include/random.hpp index 0869be19..89deed29 100644 --- a/include/random.hpp +++ b/include/random.hpp @@ -61,14 +61,12 @@ struct Xoroshiro128Plus { }; -// Simple thread-local API +// Simple global API -/** Initializes the thread-local RNG state. -Must call when creating a thread, otherwise random state is undefined (might always return 0). -*/ void init(); -/** Returns the thread-local generator. +/** Returns the generator. +Named "local" because the generator was thread-local in previous versions. */ Xoroshiro128Plus& local(); diff --git a/src/random.cpp b/src/random.cpp index 86305b4a..6b5d372b 100644 --- a/src/random.cpp +++ b/src/random.cpp @@ -1,18 +1,13 @@ -#include - -#include -#include - #include #include +#include namespace rack { namespace random { -thread_local Xoroshiro128Plus rng; -static std::atomic threadCounter {0}; +static Xoroshiro128Plus rng; void init() { @@ -20,12 +15,12 @@ void init() { if (rng.isSeeded()) return; - // Get epoch time in microseconds for seed - struct timeval tv; - gettimeofday(&tv, NULL); - uint64_t usec = uint64_t(tv.tv_sec) * 1000 * 1000 + tv.tv_usec; - // Add number of initialized threads so far to random seed, so two threads don't get the same seed if initialized at the same time. - rng.seed(usec, threadCounter++); + // Get epoch time for seed + double time = system::getUnixTime(); + uint64_t sec = time; + uint64_t nsec = std::fmod(time, 1.0) * 1e9; + rng.seed(sec, nsec); + // Shift state a few times due to low seed entropy for (int i = 0; i < 4; i++) { rng();