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
|
// Returns the number of micro-seconds since some fixed point in time. Only
|
||||||
// useful for computing deltas of time.
|
// 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;
|
virtual uint64_t NowMicros() = 0;
|
||||||
|
|
||||||
// Returns the number of nano-seconds since some fixed point in time. Only
|
// 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 {
|
virtual uint64_t NowMicros() override {
|
||||||
// all std::chrono clocks on windows have the same resolution that is only
|
// all std::chrono clocks on windows proved to return
|
||||||
// On Windows 8 and Windows 2012 Server
|
// values that may repeat that is not good enough for some uses.
|
||||||
// GetSystemTimePreciseAsFileTime(¤t_time) can be used
|
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;
|
LARGE_INTEGER li;
|
||||||
QueryPerformanceCounter(&li);
|
li.LowPart = ftSystemTime.dwLowDateTime;
|
||||||
// Convert to nanoseconds first to avoid loss of precision
|
li.HighPart = ftSystemTime.dwHighDateTime;
|
||||||
// and divide by frequency
|
// Subtract unix epoch start
|
||||||
li.QuadPart *= std::micro::den;
|
li.QuadPart -= c_UnixEpochStartTicks;
|
||||||
li.QuadPart /= perf_counter_frequency_;
|
// Convert to microsecs
|
||||||
|
li.QuadPart /= c_FtToMicroSec;
|
||||||
return li.QuadPart;
|
return li.QuadPart;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,13 +88,16 @@ bool CondVar::TimedWait(uint64_t abs_time_us) {
|
|||||||
|
|
||||||
using namespace std::chrono;
|
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 usAbsTime(abs_time_us);
|
||||||
|
|
||||||
microseconds usNow(
|
microseconds usNow(
|
||||||
duration_cast<microseconds>(system_clock::now().time_since_epoch()));
|
duration_cast<microseconds>(system_clock::now().time_since_epoch()));
|
||||||
microseconds relTimeUs =
|
microseconds relTimeUs =
|
||||||
(usAbsTime > usNow) ? (usAbsTime - usNow) : microseconds::zero();
|
(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
|
#ifndef NDEBUG
|
||||||
mu_->locked_ = true;
|
mu_->locked_ = true;
|
||||||
|
Loading…
Reference in New Issue
Block a user