diff options
author | brianderson@chromium.org <brianderson@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-03 07:22:52 +0000 |
---|---|---|
committer | brianderson@chromium.org <brianderson@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-03 07:22:52 +0000 |
commit | 61106397691808e24d086fd5b61122da10576200 (patch) | |
tree | 86894d86d11afa390e10f6bb8564cac2fff74214 | |
parent | f06d5e2c77b117ac230a0d8b3395d2bd35ef9d5d (diff) | |
download | chromium_src-61106397691808e24d086fd5b61122da10576200.zip chromium_src-61106397691808e24d086fd5b61122da10576200.tar.gz chromium_src-61106397691808e24d086fd5b61122da10576200.tar.bz2 |
Add native QPC to base::Time* conversion on Windows.
BUG=137792
Review URL: https://chromiumcodereview.appspot.com/10843038
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@149801 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | base/time.h | 5 | ||||
-rw-r--r-- | base/time_win.cc | 43 |
2 files changed, 39 insertions, 9 deletions
diff --git a/base/time.h b/base/time.h index 97010cb..389887a 100644 --- a/base/time.h +++ b/base/time.h @@ -64,6 +64,9 @@ class BASE_EXPORT TimeDelta { static TimeDelta FromSeconds(int64 secs); static TimeDelta FromMilliseconds(int64 ms); static TimeDelta FromMicroseconds(int64 us); +#if defined(OS_WIN) + static TimeDelta FromQPCValue(LONGLONG qpc_value); +#endif // Converts an integer value representing TimeDelta to a class. This is used // when deserializing a |TimeDelta| structure, using a value known to be @@ -510,6 +513,8 @@ class BASE_EXPORT TimeTicks { // Get the absolute value of QPC time drift. For testing. static int64 GetQPCDriftMicroseconds(); + static TimeTicks FromQPCValue(LONGLONG qpc_value); + // Returns true if the high resolution clock is working on this system. // This is only for testing. static bool IsHighResClockWorking(); diff --git a/base/time_win.cc b/base/time_win.cc index 71c914d..191b7a7 100644 --- a/base/time_win.cc +++ b/base/time_win.cc @@ -344,11 +344,11 @@ class HighResNowSingleton { } bool IsUsingHighResClock() { - return ticks_per_microsecond_ != 0.0; + return ticks_per_second_ != 0.0; } void DisableHighResClock() { - ticks_per_microsecond_ = 0.0; + ticks_per_second_ = 0.0; } TimeDelta Now() { @@ -371,9 +371,23 @@ class HighResNowSingleton { return abs(static_cast<long>((UnreliableNow() - ReliableNow()) - skew_)); } + int64 QPCValueToMicroseconds(LONGLONG qpc_value) { + if (!ticks_per_second_) + return 0; + + // Intentionally calculate microseconds in a round about manner to avoid + // overflow and precision issues. Think twice before simplifying! + int64 whole_seconds = qpc_value / ticks_per_second_; + int64 leftover_ticks = qpc_value % ticks_per_second_; + int64 microseconds = (whole_seconds * Time::kMicrosecondsPerSecond) + + ((leftover_ticks * Time::kMicrosecondsPerSecond) / + ticks_per_second_); + return microseconds; + } + private: HighResNowSingleton() - : ticks_per_microsecond_(0.0), + : ticks_per_second_(0), skew_(0) { InitializeClock(); @@ -389,8 +403,7 @@ class HighResNowSingleton { LARGE_INTEGER ticks_per_sec = {0}; if (!QueryPerformanceFrequency(&ticks_per_sec)) return; // Broken, we don't guarantee this function works. - ticks_per_microsecond_ = static_cast<float>(ticks_per_sec.QuadPart) / - static_cast<float>(Time::kMicrosecondsPerSecond); + ticks_per_second_ = ticks_per_sec.QuadPart; skew_ = UnreliableNow() - ReliableNow(); } @@ -399,7 +412,7 @@ class HighResNowSingleton { int64 UnreliableNow() { LARGE_INTEGER now; QueryPerformanceCounter(&now); - return static_cast<int64>(now.QuadPart / ticks_per_microsecond_); + return QPCValueToMicroseconds(now.QuadPart); } // Get the number of microseconds since boot in a reliable fashion. @@ -407,9 +420,7 @@ class HighResNowSingleton { return RolloverProtectedNow().InMicroseconds(); } - // Cached clock frequency -> microseconds. This assumes that the clock - // frequency is faster than one microsecond (which is 1MHz, should be OK). - float ticks_per_microsecond_; // 0 indicates QPF failed and we're broken. + int64 ticks_per_second_; // 0 indicates QPF failed and we're broken. int64 skew_; // Skew between lo-res and hi-res clocks (for debugging). friend struct DefaultSingletonTraits<HighResNowSingleton>; @@ -446,6 +457,20 @@ int64 TimeTicks::GetQPCDriftMicroseconds() { } // static +TimeTicks TimeTicks::FromQPCValue(LONGLONG qpc_value) { + return TimeTicks( + HighResNowSingleton::GetInstance()->QPCValueToMicroseconds(qpc_value)); +} + +// static bool TimeTicks::IsHighResClockWorking() { return HighResNowSingleton::GetInstance()->IsUsingHighResClock(); } + +// TimeDelta ------------------------------------------------------------------ + +// static +TimeDelta TimeDelta::FromQPCValue(LONGLONG qpc_value) { + return TimeDelta( + HighResNowSingleton::GetInstance()->QPCValueToMicroseconds(qpc_value)); +} |