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 |