Browse Source

Make simple random state global instead of thread-local.

tags/v2.2.0
Andrew Belt 2 years ago
parent
commit
bf675ada61
2 changed files with 11 additions and 18 deletions
  1. +3
    -5
      include/random.hpp
  2. +8
    -13
      src/random.cpp

+ 3
- 5
include/random.hpp View File

@@ -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(); void init();


/** Returns the thread-local generator.
/** Returns the generator.
Named "local" because the generator was thread-local in previous versions.
*/ */
Xoroshiro128Plus& local(); Xoroshiro128Plus& local();




+ 8
- 13
src/random.cpp View File

@@ -1,18 +1,13 @@
#include <atomic>

#include <time.h>
#include <sys/time.h>

#include <random.hpp> #include <random.hpp>
#include <math.hpp> #include <math.hpp>
#include <system.hpp>




namespace rack { namespace rack {
namespace random { namespace random {




thread_local Xoroshiro128Plus rng;
static std::atomic<uint64_t> threadCounter {0};
static Xoroshiro128Plus rng;




void init() { void init() {
@@ -20,12 +15,12 @@ void init() {
if (rng.isSeeded()) if (rng.isSeeded())
return; 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 // Shift state a few times due to low seed entropy
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
rng(); rng();


Loading…
Cancel
Save