Chromium Code Reviews| Index: src/platform/time.cc |
| diff --git a/src/platform/time.cc b/src/platform/time.cc |
| index ea6dd2c0bae6cfea3fc947b4c6f841c91a58b875..8222a40db362e7a40f92ecc23266980206ab5065 100644 |
| --- a/src/platform/time.cc |
| +++ b/src/platform/time.cc |
| @@ -43,13 +43,6 @@ |
| #include "win32-headers.h" |
| #endif |
| -#if V8_OS_WIN |
| -// Prototype for GetTickCount64() procedure. |
| -extern "C" { |
| -typedef ULONGLONG (WINAPI *GETTICKCOUNT64PROC)(void); |
| -} |
| -#endif |
| - |
| namespace v8 { |
| namespace internal { |
| @@ -175,43 +168,43 @@ struct timespec TimeDelta::ToTimespec() const { |
| // periodically resync the internal clock to the system clock. |
| class Clock V8_FINAL { |
| public: |
| - Clock() : initial_time_(CurrentWallclockTime()), |
| - initial_ticks_(TimeTicks::Now()) {} |
| + Clock() : initial_ticks_(GetSystemTicks()), initial_time_(GetSystemTime()) {} |
| Time Now() { |
| - // This must be executed under lock. |
| - LockGuard<Mutex> lock_guard(&mutex_); |
| + // Time between resampling the un-granular clock for this API (1 minute). |
| + const TimeDelta kMaxElapsedTime = TimeDelta::FromMinutes(1); |
| - // Calculate the time elapsed since we started our timer. |
| - TimeDelta elapsed = TimeTicks::Now() - initial_ticks_; |
| + LockGuard<Mutex> lock_guard(&mutex_); |
| - // Check if we don't need to synchronize with the wallclock yet. |
| - if (elapsed.InMicroseconds() <= kMaxMicrosecondsToAvoidDrift) { |
| - return initial_time_ + elapsed; |
| + // Determine current time and ticks. |
| + TimeTicks ticks = GetSystemTicks(); |
| + Time time = GetSystemTime(); |
| + |
| + // Check if we need to resynchronize due to backwards time |
|
Hannes Payer (out of office)
2013/10/02 11:27:25
Move words up until you hit the 80 chars barrier.
Benedikt Meurer
2013/10/02 12:27:46
Done.
|
| + // change or elapsed time. |
|
Hannes Payer (out of office)
2013/10/02 11:27:25
What do you mean here? Should it be "Check if we h
Benedikt Meurer
2013/10/02 12:27:46
Done.
|
| + TimeDelta elapsed = ticks - initial_ticks_; |
| + if (time < initial_time_ || elapsed > kMaxElapsedTime) { |
| + initial_ticks_ = ticks; |
| + initial_time_ = time; |
| + return time; |
| } |
| - // Resynchronize with the wallclock. |
| - initial_ticks_ = TimeTicks::Now(); |
| - initial_time_ = CurrentWallclockTime(); |
| - return initial_time_; |
| + return initial_time_ + elapsed; |
| } |
| Time NowFromSystemTime() { |
| - // This must be executed under lock. |
| LockGuard<Mutex> lock_guard(&mutex_); |
| - |
| - // Resynchronize with the wallclock. |
| - initial_ticks_ = TimeTicks::Now(); |
| - initial_time_ = CurrentWallclockTime(); |
| + initial_ticks_ = GetSystemTicks(); |
| + initial_time_ = GetSystemTime(); |
| return initial_time_; |
| } |
| private: |
| - // Time between resampling the un-granular clock for this API (1 minute). |
| - static const int64_t kMaxMicrosecondsToAvoidDrift = |
| - Time::kMicrosecondsPerMinute; |
| + static TimeTicks GetSystemTicks() { |
| + return TimeTicks::Now(); |
| + } |
| - static Time CurrentWallclockTime() { |
| + static Time GetSystemTime() { |
| FILETIME ft; |
| ::GetSystemTimeAsFileTime(&ft); |
| return Time::FromFiletime(ft); |
| @@ -223,9 +216,9 @@ class Clock V8_FINAL { |
| }; |
| -static LazyDynamicInstance<Clock, |
| - DefaultCreateTrait<Clock>, |
| - ThreadSafeInitOnceTrait>::type clock = LAZY_DYNAMIC_INSTANCE_INITIALIZER; |
| +static LazyStaticInstance<Clock, |
| + DefaultConstructTrait<Clock>, |
| + ThreadSafeInitOnceTrait>::type clock = LAZY_STATIC_INSTANCE_INITIALIZER; |
| Time Time::Now() { |
| @@ -388,6 +381,7 @@ class TickClock { |
| public: |
| virtual ~TickClock() {} |
| virtual int64_t Now() = 0; |
| + virtual bool IsHighResolution() =0; |
|
Hannes Payer (out of office)
2013/10/02 11:27:25
space missing
Benedikt Meurer
2013/10/02 12:27:46
Done.
|
| }; |
| @@ -445,30 +439,12 @@ class HighResolutionTickClock V8_FINAL : public TickClock { |
| return ticks + 1; |
| } |
| - private: |
| - int64_t ticks_per_second_; |
| -}; |
| - |
| - |
| -// The GetTickCount64() API is what we actually want for the regular tick |
| -// clock, but this is only available starting with Windows Vista. |
| -class WindowsVistaTickClock V8_FINAL : public TickClock { |
| - public: |
| - explicit WindowsVistaTickClock(GETTICKCOUNT64PROC func) : func_(func) { |
| - ASSERT(func_ != NULL); |
| - } |
| - virtual ~WindowsVistaTickClock() {} |
| - |
| - virtual int64_t Now() V8_OVERRIDE { |
| - // Query the current ticks (in ms). |
| - ULONGLONG tick_count_ms = (*func_)(); |
| - |
| - // Convert to microseconds (make sure to never return 0 here). |
| - return (tick_count_ms * Time::kMicrosecondsPerMillisecond) + 1; |
| + virtual bool IsHighResolution() V8_OVERRIDE { |
| + return true; |
| } |
| private: |
| - GETTICKCOUNT64PROC func_; |
| + int64_t ticks_per_second_; |
| }; |
| @@ -487,6 +463,10 @@ class RolloverProtectedTickClock V8_FINAL : public TickClock { |
| // Note that we do not use GetTickCount() here, since timeGetTime() gives |
| // more predictable delta values, as described here: |
| // http://blogs.msdn.com/b/larryosterman/archive/2009/09/02/what-s-the-difference-between-gettickcount-and-timegettime.aspx |
|
Hannes Payer (out of office)
2013/10/02 11:27:25
can we fix that link - 80 chars
Benedikt Meurer
2013/10/02 12:27:46
As discussed offline, this is how we do it in othe
|
| + // |
|
Hannes Payer (out of office)
2013/10/02 11:27:25
remove that // with a newline
Benedikt Meurer
2013/10/02 12:27:46
Done.
|
| + // timeGetTime() provides 1ms granularity when combined with |
| + // timeBeginPeriod(). If the host application for V8 wants fast timers, it |
| + // can use timeBeginPeriod() to increase the resolution. |
| DWORD now = timeGetTime(); |
| if (now < last_seen_now_) { |
| rollover_ms_ += V8_INT64_C(0x100000000); // ~49.7 days. |
| @@ -495,6 +475,10 @@ class RolloverProtectedTickClock V8_FINAL : public TickClock { |
| return (now + rollover_ms_) * Time::kMicrosecondsPerMillisecond; |
| } |
| + virtual bool IsHighResolution() V8_OVERRIDE { |
| + return false; |
| + } |
| + |
| private: |
| Mutex mutex_; |
| DWORD last_seen_now_; |
| @@ -502,27 +486,10 @@ class RolloverProtectedTickClock V8_FINAL : public TickClock { |
| }; |
| -struct CreateTickClockTrait { |
| - static TickClock* Create() { |
| - // Try to load GetTickCount64() from kernel32.dll (available since Vista). |
| - HMODULE kernel32 = ::GetModuleHandleA("kernel32.dll"); |
| - ASSERT(kernel32 != NULL); |
| - FARPROC proc = ::GetProcAddress(kernel32, "GetTickCount64"); |
| - if (proc != NULL) { |
| - return new WindowsVistaTickClock( |
| - reinterpret_cast<GETTICKCOUNT64PROC>(proc)); |
| - } |
| - |
| - // Fallback to the rollover protected tick clock. |
| - return new RolloverProtectedTickClock; |
| - } |
| -}; |
| - |
| - |
| -static LazyDynamicInstance<TickClock, |
| - CreateTickClockTrait, |
| +static LazyStaticInstance<RolloverProtectedTickClock, |
| + DefaultConstructTrait<RolloverProtectedTickClock>, |
| ThreadSafeInitOnceTrait>::type tick_clock = |
| - LAZY_DYNAMIC_INSTANCE_INITIALIZER; |
| + LAZY_STATIC_INSTANCE_INITIALIZER; |
| struct CreateHighResTickClockTrait { |
| @@ -567,6 +534,12 @@ TimeTicks TimeTicks::HighResNow() { |
| return ticks; |
| } |
| + |
| +// static |
| +bool TimeTicks::IsHighResClockWorking() { |
| + return high_res_tick_clock.Pointer()->IsHighResolution(); |
| +} |
| + |
| #else // V8_OS_WIN |
| TimeTicks TimeTicks::Now() { |
| @@ -608,6 +581,12 @@ TimeTicks TimeTicks::HighResNow() { |
| return TimeTicks(ticks + 1); |
| } |
| + |
| +// static |
| +bool TimeTicks::IsHighResClockWorking() { |
| + return true; |
| +} |
| + |
| #endif // V8_OS_WIN |
| } } // namespace v8::internal |