diff options
author | Pieter Wuille <pieter.wuille@gmail.com> | 2017-05-02 18:21:33 -0700 |
---|---|---|
committer | Pieter Wuille <pieter.wuille@gmail.com> | 2017-05-05 11:56:19 -0700 |
commit | f544094d5e1ee627ebd34542aead7bf1241fae19 (patch) | |
tree | b56a7c9cbf9056885b1fb8914a872fc4820fff54 | |
parent | 75171f099e82e3527d7c3469b15891bd92227ec2 (diff) |
Use hardware timestamps in RNG seeding
-rw-r--r-- | src/random.cpp | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/src/random.cpp b/src/random.cpp index 6187f16290..40879e8737 100644 --- a/src/random.cpp +++ b/src/random.cpp @@ -16,6 +16,7 @@ #include <stdlib.h> #include <limits> +#include <chrono> #ifndef WIN32 #include <sys/time.h> @@ -43,15 +44,22 @@ static void RandFailure() static inline int64_t GetPerformanceCounter() { - int64_t nCounter = 0; -#ifdef WIN32 - QueryPerformanceCounter((LARGE_INTEGER*)&nCounter); + // Read the hardware time stamp counter when available. + // See https://en.wikipedia.org/wiki/Time_Stamp_Counter for more information. +#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) + return __rdtsc(); +#elif !defined(_MSC_VER) && defined(__i386__) + uint64_t r = 0; + __asm__ volatile ("rdtsc" : "=A"(r)); // Constrain the r variable to the eax:edx pair. + return r; +#elif !defined(_MSC_VER) && (defined(__x86_64__) || defined(__amd64__)) + uint64_t r1 = 0, r2 = 0; + __asm__ volatile ("rdtsc" : "=a"(r1), "=d"(r2)); // Constrain r1 to rax and r2 to rdx. + return (r2 << 32) | r1; #else - timeval t; - gettimeofday(&t, NULL); - nCounter = (int64_t)(t.tv_sec * 1000000 + t.tv_usec); + // Fall back to using C++11 clock (usually microsecond or nanosecond precision) + return std::chrono::high_resolution_clock::now().time_since_epoch().count(); #endif - return nCounter; } void RandAddSeed() |