Reviewers: yurys, caseq,

Description:
Fix CPU profiler deadlock on Windows + AMD CPU.

Implement a lock free version of RolloverProtectedTickClock::Now
to eliminate a deadlock.

BUG=521420
LOG=Y

Please review this at https://codereview.chromium.org/1304873011/

Base URL: https://chromium.googlesource.com/v8/v8.git@master

Affected files (+13, -13 lines):
  M src/base/platform/time.cc


Index: src/base/platform/time.cc
diff --git a/src/base/platform/time.cc b/src/base/platform/time.cc
index 7e4c8fc0ac902db962fa3b5a3337f1e876ebd561..1e01d9ac04e056fb64aa184df83e8048e53e73af 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_);
+    base::Atomic32 now = static_cast<base::Atomic32>(timeGetTime());
+    if ((now >> 31) != (rollover & 1)) {
+      base::Release_CompareAndSwap(&rollover_, rollover, rollover + 1);
+      ++rollover;
     }
-    last_seen_now_ = now;
-    return (now + rollover_ms_) * Time::kMicrosecondsPerMillisecond;
+    int64_t rollover_ms = static_cast<int64_t>(rollover) << 31;
+    return (rollover_ms | now) * Time::kMicrosecondsPerMillisecond;
   }

   bool IsHighResolution() override { return false; }

  private:
-  Mutex mutex_;
-  DWORD last_seen_now_;
-  int64_t rollover_ms_;
+  base::Atomic32 rollover_;
 };




--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to