mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-03 17:05:50 +00:00
Reduce calls to std::random_device:
Existing per-thread PRNGs are individually initialized using calls
to std::random_device.
If merged, this commit will use a single PRNG, initialized from
std::random_device on startup, to seed the thread-specific PRNGs.
Acknowledgements:
Thomas Snider, who reported this issue to Ripple on April 8, 2020.
This commit is contained in:
@@ -21,13 +21,13 @@
|
||||
#define RIPPLE_BASICS_RANDOM_H_INCLUDED
|
||||
|
||||
#include <ripple/beast/xor_shift_engine.h>
|
||||
#include <boost/thread/tss.hpp>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <random>
|
||||
#include <limits>
|
||||
#include <mutex>
|
||||
#include <ripple/beast/cxx17/type_traits.h> // <type_traits>
|
||||
|
||||
namespace ripple {
|
||||
@@ -67,27 +67,30 @@ inline
|
||||
beast::xor_shift_engine&
|
||||
default_prng ()
|
||||
{
|
||||
static
|
||||
boost::thread_specific_ptr<beast::xor_shift_engine> engine;
|
||||
|
||||
if (!engine.get())
|
||||
// This is used to seed the thread-specific PRNGs on demand
|
||||
static beast::xor_shift_engine seeder = []
|
||||
{
|
||||
std::random_device rng;
|
||||
std::uniform_int_distribution<std::uint64_t> distribution{1};
|
||||
return beast::xor_shift_engine(distribution(rng));
|
||||
}();
|
||||
|
||||
std::uint64_t seed = rng();
|
||||
// This protects the seeder
|
||||
static std::mutex m;
|
||||
|
||||
for (int i = 0; i < 6; ++i)
|
||||
// The thread-specific PRNGs:
|
||||
thread_local beast::xor_shift_engine engine = []
|
||||
{
|
||||
std::uint64_t seed;
|
||||
{
|
||||
if (seed == 0)
|
||||
seed = rng();
|
||||
|
||||
seed ^= (seed << (7 - i)) * rng();
|
||||
std::lock_guard lk(m);
|
||||
std::uniform_int_distribution<std::uint64_t> distribution{1};
|
||||
seed = distribution(seeder);
|
||||
}
|
||||
return beast::xor_shift_engine{seed};
|
||||
}();
|
||||
|
||||
engine.reset (new beast::xor_shift_engine (seed));
|
||||
}
|
||||
|
||||
return *engine;
|
||||
return engine;
|
||||
}
|
||||
|
||||
/** Return a uniformly distributed random integer.
|
||||
@@ -100,8 +103,8 @@ default_prng ()
|
||||
|
||||
The randomness is generated by the specified engine (or
|
||||
the default engine if one is not specified). The result
|
||||
is only cryptographicallys secure if the PRNG engine is
|
||||
cryptographically secure.
|
||||
is cryptographically secure only when the engine passed
|
||||
into the function is cryptographically secure.
|
||||
|
||||
@note The range is always a closed interval, so calling
|
||||
rand_int(-5, 15) can return any integer in the
|
||||
|
||||
Reference in New Issue
Block a user