Use hardware timestamps in RNG seeding

This commit is contained in:
Pieter Wuille 2017-05-02 18:21:33 -07:00
parent 75171f099e
commit f544094d5e

View file

@ -16,6 +16,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <limits> #include <limits>
#include <chrono>
#ifndef WIN32 #ifndef WIN32
#include <sys/time.h> #include <sys/time.h>
@ -43,15 +44,22 @@ static void RandFailure()
static inline int64_t GetPerformanceCounter() static inline int64_t GetPerformanceCounter()
{ {
int64_t nCounter = 0; // Read the hardware time stamp counter when available.
#ifdef WIN32 // See https://en.wikipedia.org/wiki/Time_Stamp_Counter for more information.
QueryPerformanceCounter((LARGE_INTEGER*)&nCounter); #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 #else
timeval t; // Fall back to using C++11 clock (usually microsecond or nanosecond precision)
gettimeofday(&t, NULL); return std::chrono::high_resolution_clock::now().time_since_epoch().count();
nCounter = (int64_t)(t.tv_sec * 1000000 + t.tv_usec);
#endif #endif
return nCounter;
} }
void RandAddSeed() void RandAddSeed()