aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPieter Wuille <pieter.wuille@gmail.com>2017-05-02 18:21:33 -0700
committerPieter Wuille <pieter.wuille@gmail.com>2017-05-05 11:56:19 -0700
commitf544094d5e1ee627ebd34542aead7bf1241fae19 (patch)
treeb56a7c9cbf9056885b1fb8914a872fc4820fff54
parent75171f099e82e3527d7c3469b15891bd92227ec2 (diff)
Use hardware timestamps in RNG seeding
-rw-r--r--src/random.cpp22
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()