Bug 1500805 Part 2 - Ensure non-main threads are idle when diverging from the recording, r=mccr8.
authorBrian Hackett <bhackett1024@gmail.com>
Sun, 21 Oct 2018 15:02:32 -0600
changeset 443016 20691f6e5da854dabedc2c2beb97133599cec868
parent 443015 25e1e5dcacb2d8a968167ba7e3775e1fcd862590
child 443017 ac631ceaa2b95d5c44f470cffba8bd1b339b0403
push id34934
push userccoroiu@mozilla.com
push dateThu, 25 Oct 2018 21:57:20 +0000
treeherdermozilla-central@1e44ac3b69a4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmccr8
bugs1500805
milestone65.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1500805 Part 2 - Ensure non-main threads are idle when diverging from the recording, r=mccr8.
toolkit/recordreplay/ProcessRewind.cpp
toolkit/recordreplay/ipc/ChildIPC.cpp
--- a/toolkit/recordreplay/ProcessRewind.cpp
+++ b/toolkit/recordreplay/ProcessRewind.cpp
@@ -194,16 +194,21 @@ DivergeFromRecording()
 
   Thread* thread = Thread::Current();
   MOZ_RELEASE_ASSERT(thread->IsMainThread());
 
   if (!thread->HasDivergedFromRecording()) {
     // Reset middleman call state whenever we first diverge from the recording.
     child::SendResetMiddlemanCalls();
 
+    // Make sure all non-main threads are idle before we begin diverging. This
+    // thread's new behavior can change values used by other threads and induce
+    // recording mismatches.
+    Thread::WaitForIdleThreads();
+
     thread->DivergeFromRecording();
   }
 
   gUnhandledDivergeAllowed = true;
 }
 
 extern "C" {
 
--- a/toolkit/recordreplay/ipc/ChildIPC.cpp
+++ b/toolkit/recordreplay/ipc/ChildIPC.cpp
@@ -572,32 +572,31 @@ Repaint(size_t* aWidth, size_t* aHeight)
     return;
   }
 
   // Ignore the request to repaint if the compositor thread has already
   // diverged from the recording. In this case we have already done a repaint
   // and the last graphics we sent will still be correct.
   Thread* compositorThread = Thread::GetById(gCompositorThreadId);
   if (!compositorThread->WillDivergeFromRecordingSoon()) {
+    // Allow the compositor to diverge from the recording so it can perform
+    // any paint we are about to trigger, or finish any in flight paint that
+    // that existed at the point we are paused at.
+    Thread::GetById(gCompositorThreadId)->SetShouldDivergeFromRecording();
+    Thread::ResumeSingleIdleThread(gCompositorThreadId);
+
     // Create an artifical vsync to see if graphics have changed since the last
     // paint and a new paint is needed.
     NotifyVsyncObserver();
 
-    if (gNumPendingPaints) {
-      // Allow the compositor to diverge from the recording so it can perform
-      // any paint we just triggered, or finish any in flight paint that that
-      // existed at the point we are paused at.
-      Thread::GetById(gCompositorThreadId)->SetShouldDivergeFromRecording();
-
-      // Wait for the compositor to finish all in flight paints, including any
-      // one we just triggered.
-      MonitorAutoLock lock(*gMonitor);
-      while (gNumPendingPaints) {
-        gMonitor->Wait();
-      }
+    // Wait for the compositor to finish all in flight paints, including any
+    // one we just triggered.
+    MonitorAutoLock lock(*gMonitor);
+    while (gNumPendingPaints) {
+      gMonitor->Wait();
     }
   }
 
   if (gDrawTargetBuffer) {
     memcpy(gGraphicsShmem, gDrawTargetBuffer, gDrawTargetBufferSize);
     *aWidth = gPaintWidth;
     *aHeight = gPaintHeight;
   } else {