Index: src/base/platform/time.cc |
diff --git a/src/base/platform/time.cc b/src/base/platform/time.cc |
index 7e4c8fc0ac902db962fa3b5a3337f1e876ebd561..5162182b7a3555a2e07cf2b5e345c98eaccfc99b 100644 |
--- a/src/base/platform/time.cc |
+++ b/src/base/platform/time.cc |
@@ -17,6 +17,7 @@ |
#include <ostream> |
#if V8_OS_WIN |
+#include "src/base/atomicops.h" |
#include "src/base/lazy-instance.h" |
#include "src/base/win32-headers.h" |
#endif |
@@ -434,36 +435,35 @@ class HighResolutionTickClock final : public TickClock { |
class RolloverProtectedTickClock final : public TickClock { |
public: |
- // We initialize rollover_ms_ to 1 to ensure that we will never |
- // return 0 from TimeTicks::HighResolutionNow() and TimeTicks::Now() below. |
- RolloverProtectedTickClock() : last_seen_now_(0), rollover_ms_(1) {} |
+ RolloverProtectedTickClock() : rollover_(0) {} |
virtual ~RolloverProtectedTickClock() {} |
int64_t Now() override { |
- LockGuard<Mutex> lock_guard(&mutex_); |
// We use timeGetTime() to implement TimeTicks::Now(), which rolls over |
// every ~49.7 days. We try to track rollover ourselves, which works if |
- // TimeTicks::Now() is called at least every 49 days. |
+ // TimeTicks::Now() is called at least every 24 days. |
// 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 |
// 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. |
+ // We use a lock-free version because the sampler thread calls it |
+ // while having the rest of the world stopped, that could cause a deadlock. |
+ base::Atomic32 rollover = base::Acquire_Load(&rollover_); |
+ uint32_t now = static_cast<uint32_t>(timeGetTime()); |
+ if ((now >> 31) != static_cast<uint32_t>(rollover & 1)) { |
+ base::Release_CompareAndSwap(&rollover_, rollover, rollover + 1); |
+ ++rollover; |
} |
- last_seen_now_ = now; |
- return (now + rollover_ms_) * Time::kMicrosecondsPerMillisecond; |
+ uint64_t ms = (static_cast<uint64_t>(rollover) << 31) | now; |
+ return static_cast<int64_t>(ms * Time::kMicrosecondsPerMillisecond); |
} |
bool IsHighResolution() override { return false; } |
private: |
- Mutex mutex_; |
- DWORD last_seen_now_; |
- int64_t rollover_ms_; |
+ base::Atomic32 rollover_; |
}; |