Bug 1128768: Part 3 - Update BHR to allow for hang annotations; r=vladan
authorAaron Klotz <aklotz@mozilla.com>
Wed, 18 Feb 2015 23:22:01 -0700
changeset 232585 c3501a329f69bad4ab9f90bc827c69758f1a5d49
parent 232584 13eb8592325c6886fd8f02b7b0390120f08ac503
child 232586 2f0b44330ffb6aca66f4caa0f6ea38cbd5b15f6a
push id56615
push useraklotz@mozilla.com
push dateTue, 10 Mar 2015 01:45:08 +0000
treeherdermozilla-inbound@0df0abc0f58c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersvladan
bugs1128768
milestone39.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 1128768: Part 3 - Update BHR to allow for hang annotations; r=vladan
xpcom/threads/BackgroundHangMonitor.cpp
xpcom/threads/BackgroundHangMonitor.h
--- a/xpcom/threads/BackgroundHangMonitor.cpp
+++ b/xpcom/threads/BackgroundHangMonitor.cpp
@@ -135,16 +135,20 @@ public:
   // Is the thread in a waiting state
   bool mWaiting;
   // Platform-specific helper to get hang stacks
   ThreadStackHelper mStackHelper;
   // Stack of current hang
   Telemetry::HangStack mHangStack;
   // Statistics for telemetry
   Telemetry::ThreadHangStats mStats;
+  // Annotations for the current hang
+  UniquePtr<HangMonitor::HangAnnotations> mAnnotations;
+  // Annotators registered for this thread
+  HangMonitor::Observer::Annotators mAnnotators;
 
   BackgroundHangThread(const char* aName,
                        uint32_t aTimeoutMs,
                        uint32_t aMaxTimeoutMs);
 
   // Report a hang; aManager->mLock IS locked
   Telemetry::HangHistogram& ReportHang(PRIntervalTime aHangTime);
   // Report a permanent hang; aManager->mLock IS locked
@@ -269,16 +273,18 @@ BackgroundHangManager::RunMonitorThread(
       }
 
       if (MOZ_LIKELY(!currentThread->mHanging)) {
         if (MOZ_UNLIKELY(hangTime >= currentThread->mTimeout)) {
           // A hang started
           currentThread->mStackHelper.GetStack(currentThread->mHangStack);
           currentThread->mHangStart = interval;
           currentThread->mHanging = true;
+          currentThread->mAnnotations =
+            currentThread->mAnnotators.GatherAnnotations();
         }
       } else {
         if (MOZ_LIKELY(interval != currentThread->mHangStart)) {
           // A hang ended
           currentThread->ReportHang(intervalNow - currentThread->mHangStart);
           currentThread->mHanging = false;
         }
       }
@@ -367,22 +373,22 @@ BackgroundHangThread::ReportHang(PRInter
     }
   }
 
   Telemetry::HangHistogram newHistogram(Move(mHangStack));
   for (Telemetry::HangHistogram* oldHistogram = mStats.mHangs.begin();
        oldHistogram != mStats.mHangs.end(); oldHistogram++) {
     if (newHistogram == *oldHistogram) {
       // New histogram matches old one
-      oldHistogram->Add(aHangTime);
+      oldHistogram->Add(aHangTime, Move(mAnnotations));
       return *oldHistogram;
     }
   }
   // Add new histogram
-  newHistogram.Add(aHangTime);
+  newHistogram.Add(aHangTime, Move(mAnnotations));
   mStats.mHangs.append(Move(newHistogram));
   return mStats.mHangs.back();
 }
 
 void
 BackgroundHangThread::ReportPermaHang()
 {
   // Permanently hanged; called on the monitor thread
@@ -551,16 +557,43 @@ BackgroundHangMonitor::Allow()
 {
 #ifdef MOZ_ENABLE_BACKGROUND_HANG_MONITOR
   MOZ_ASSERT(BackgroundHangManager::sInstance == nullptr,
              "The background hang monitor is already initialized");
   BackgroundHangManager::sProhibited = false;
 #endif
 }
 
+bool
+BackgroundHangMonitor::RegisterAnnotator(HangMonitor::Annotator& aAnnotator)
+{
+#ifdef MOZ_ENABLE_BACKGROUND_HANG_MONITOR
+  BackgroundHangThread* thisThread = BackgroundHangThread::FindThread();
+  if (!thisThread) {
+    return false;
+  }
+  return thisThread->mAnnotators.Register(aAnnotator);
+#else
+  return false;
+#endif
+}
+
+bool
+BackgroundHangMonitor::UnregisterAnnotator(HangMonitor::Annotator& aAnnotator)
+{
+#ifdef MOZ_ENABLE_BACKGROUND_HANG_MONITOR
+  BackgroundHangThread* thisThread = BackgroundHangThread::FindThread();
+  if (!thisThread) {
+    return false;
+  }
+  return thisThread->mAnnotators.Unregister(aAnnotator);
+#else
+  return false;
+#endif
+}
 
 /* Because we are iterating through the BackgroundHangThread linked list,
    we need to take a lock. Using MonitorAutoLock as a base class makes
    sure all of that is taken care of for us. */
 BackgroundHangMonitor::ThreadHangStatsIterator::ThreadHangStatsIterator()
   : MonitorAutoLock(BackgroundHangManager::sInstance->mLock)
   , mThread(BackgroundHangManager::sInstance ?
             BackgroundHangManager::sInstance->mHangThreads.getFirst() :
--- a/xpcom/threads/BackgroundHangMonitor.h
+++ b/xpcom/threads/BackgroundHangMonitor.h
@@ -2,18 +2,19 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_BackgroundHangMonitor_h
 #define mozilla_BackgroundHangMonitor_h
 
+#include "mozilla/HangAnnotations.h"
+#include "mozilla/Monitor.h"
 #include "mozilla/RefPtr.h"
-#include "mozilla/Monitor.h"
 
 #include <stdint.h>
 
 namespace mozilla {
 
 namespace Telemetry {
 class ThreadHangStats;
 };
@@ -222,13 +223,28 @@ public:
   /**
    * Allow the hang monitor to run.
    *
    * Allow() and Prohibit() should be called in pair.
    *
    * \see Prohibit()
    */
   static void Allow();
+
+  /**
+   * Register an annotator with BHR for the current thread.
+   * @param aAnnotator annotator to register
+   * @return true if the annotator was registered, otherwise false.
+   */
+  static bool RegisterAnnotator(HangMonitor::Annotator& aAnnotator);
+
+  /**
+   * Unregister an annotator that was previously registered via
+   * RegisterAnnotator.
+   * @param aAnnotator annotator to unregister
+   * @return true if there are still remaining annotators registered
+   */
+  static bool UnregisterAnnotator(HangMonitor::Annotator& aAnnotator);
 };
 
 } // namespace mozilla
 
 #endif // mozilla_BackgroundHangMonitor_h