X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2FRandom.cpp;h=e69a4452564e0fb32744cbf3e05d28b5dd37b089;hb=ff03c3a89d70f49f5fdedcb1e6af7a1c9fc9bacb;hp=24486452214d880b5470b41992cded1440ecb87b;hpb=22afce906d7e98d95f8c45c3301072d9fd891d41;p=folly.git diff --git a/folly/Random.cpp b/folly/Random.cpp index 24486452..e69a4452 100644 --- a/folly/Random.cpp +++ b/folly/Random.cpp @@ -19,6 +19,13 @@ #include #include #include +#include +#include + +#if __GNUC_PREREQ(4, 8) +#include +#define USE_SIMD_PRNG +#endif namespace folly { @@ -28,7 +35,7 @@ std::atomic seedInput(0); uint32_t randomNumberSeed() { struct timeval tv; - gettimeofday(&tv, NULL); + gettimeofday(&tv, nullptr); const uint32_t kPrime0 = 51551; const uint32_t kPrime1 = 61631; const uint32_t kPrime2 = 64997; @@ -39,4 +46,39 @@ uint32_t randomNumberSeed() { + kPrime3 * static_cast(tv.tv_usec); } + +folly::ThreadLocalPtr +ThreadLocalPRNG::localInstance; + +class ThreadLocalPRNG::LocalInstancePRNG { +#ifdef USE_SIMD_PRNG + typedef __gnu_cxx::sfmt19937 RNG; +#else + typedef std::mt19937 RNG; +#endif + + static RNG makeRng() { + std::array seed_data; + std::random_device r; + std::generate_n(seed_data.data(), seed_data.size(), std::ref(r)); + std::seed_seq seq(std::begin(seed_data), std::end(seed_data)); + return RNG(seq); + } + + public: + LocalInstancePRNG() : rng(std::move(makeRng())) {} + + RNG rng; +}; + +ThreadLocalPRNG::LocalInstancePRNG* ThreadLocalPRNG::initLocal() { + auto ret = new LocalInstancePRNG; + localInstance.reset(ret); + return ret; +} + +uint32_t ThreadLocalPRNG::getImpl(LocalInstancePRNG* local) { + return local->rng(); +} + }