Merge pull request #705 from yuslepukhin/rate_limiter_fix
Make WinEnv::NowMicros return system time
This commit is contained in:
commit
0f763db20a
@ -257,6 +257,8 @@ class Env {
|
||||
|
||||
// Returns the number of micro-seconds since some fixed point in time. Only
|
||||
// useful for computing deltas of time.
|
||||
// However, it is often used as system time such as in GenericRateLimiter
|
||||
// and other places so a port needs to return system time in order to work.
|
||||
virtual uint64_t NowMicros() = 0;
|
||||
|
||||
// Returns the number of nano-seconds since some fixed point in time. Only
|
||||
|
@ -1816,15 +1816,24 @@ class WinEnv : public Env {
|
||||
}
|
||||
|
||||
virtual uint64_t NowMicros() override {
|
||||
// all std::chrono clocks on windows have the same resolution that is only
|
||||
// On Windows 8 and Windows 2012 Server
|
||||
// GetSystemTimePreciseAsFileTime(¤t_time) can be used
|
||||
// all std::chrono clocks on windows proved to return
|
||||
// values that may repeat that is not good enough for some uses.
|
||||
const int64_t c_UnixEpochStartTicks = 116444736000000000i64;
|
||||
const int64_t c_FtToMicroSec = 10;
|
||||
|
||||
// This interface needs to return system time and not
|
||||
// just any microseconds because it is often used as an argument
|
||||
// to TimedWait() on condition variable
|
||||
FILETIME ftSystemTime;
|
||||
GetSystemTimePreciseAsFileTime(&ftSystemTime);
|
||||
|
||||
LARGE_INTEGER li;
|
||||
QueryPerformanceCounter(&li);
|
||||
// Convert to nanoseconds first to avoid loss of precision
|
||||
// and divide by frequency
|
||||
li.QuadPart *= std::micro::den;
|
||||
li.QuadPart /= perf_counter_frequency_;
|
||||
li.LowPart = ftSystemTime.dwLowDateTime;
|
||||
li.HighPart = ftSystemTime.dwHighDateTime;
|
||||
// Subtract unix epoch start
|
||||
li.QuadPart -= c_UnixEpochStartTicks;
|
||||
// Convert to microsecs
|
||||
li.QuadPart /= c_FtToMicroSec;
|
||||
return li.QuadPart;
|
||||
}
|
||||
|
||||
|
@ -88,13 +88,16 @@ bool CondVar::TimedWait(uint64_t abs_time_us) {
|
||||
|
||||
using namespace std::chrono;
|
||||
|
||||
// MSVC++ library implements wait_until in terms of wait_for so
|
||||
// there is not an absolute wait anyway.
|
||||
microseconds usAbsTime(abs_time_us);
|
||||
|
||||
microseconds usNow(
|
||||
duration_cast<microseconds>(system_clock::now().time_since_epoch()));
|
||||
microseconds relTimeUs =
|
||||
(usAbsTime > usNow) ? (usAbsTime - usNow) : microseconds::zero();
|
||||
|
||||
std::_Cv_status cvStatus = cv_.wait_for(mu_->getLock(), relTimeUs);
|
||||
std::cv_status cvStatus = cv_.wait_for(mu_->getLock(), relTimeUs);
|
||||
|
||||
#ifndef NDEBUG
|
||||
mu_->locked_ = true;
|
||||
|
Loading…
Reference in New Issue
Block a user