Bug 932865 - Collect thread hang stats in BackgroundHangMonitor; r=froydnj

This commit is contained in:
Jim Chen 2013-11-22 14:17:31 -05:00
parent 20a30949cd
commit 9d818e8444

View File

@ -6,6 +6,7 @@
#include "mozilla/BackgroundHangMonitor.h"
#include "mozilla/LinkedList.h"
#include "mozilla/Monitor.h"
#include "mozilla/Move.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/Telemetry.h"
#include "mozilla/ThreadHangStats.h"
@ -13,6 +14,7 @@
#include "prinrval.h"
#include "prthread.h"
#include "ThreadStackHelper.h"
#include <algorithm>
@ -117,6 +119,10 @@ public:
bool mHanging;
// Is the thread in a waiting state
bool mWaiting;
// Platform-specific helper to get hang stacks
ThreadStackHelper mStackHelper;
// Stack of current hang
Telemetry::HangHistogram::Stack mHangStack;
// Statistics for telemetry
Telemetry::ThreadHangStats mStats;
@ -126,7 +132,7 @@ public:
~BackgroundHangThread();
// Report a hang; aManager->mLock IS locked
void ReportHang(PRIntervalTime aHangTime) const;
void ReportHang(PRIntervalTime aHangTime);
// Report a permanent hang; aManager->mLock IS locked
void ReportPermaHang() const;
// Called by BackgroundHangMonitor::NotifyActivity
@ -253,6 +259,7 @@ 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;
}
@ -332,12 +339,23 @@ BackgroundHangThread::~BackgroundHangThread()
}
void
BackgroundHangThread::ReportHang(PRIntervalTime aHangTime) const
BackgroundHangThread::ReportHang(PRIntervalTime aHangTime)
{
// Recovered from a hang; called on the monitor thread
// mManager->mLock IS locked
// TODO: Add telemetry reporting for hangs
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);
return;
}
}
// Add new histogram
newHistogram.Add(aHangTime);
mStats.mHangs.append(Move(newHistogram));
}
void
@ -361,6 +379,7 @@ BackgroundHangThread::NotifyActivity()
mManager->Wakeup();
} else {
PRIntervalTime duration = intervalNow - mInterval;
mStats.mActivity.Add(duration);
if (MOZ_UNLIKELY(duration >= mTimeout)) {
/* Wake up the manager thread to tell it that a hang ended */
mManager->Wakeup();
@ -398,6 +417,7 @@ void
BackgroundHangMonitor::Startup()
{
MOZ_ASSERT(!BackgroundHangManager::sInstance, "Already initialized");
ThreadStackHelper::Startup();
BackgroundHangThread::Startup();
BackgroundHangManager::sInstance = new BackgroundHangManager();
}
@ -411,6 +431,7 @@ BackgroundHangMonitor::Shutdown()
we don't want to hold the lock when it's being destroyed. */
BackgroundHangManager::sInstance->Shutdown();
BackgroundHangManager::sInstance = nullptr;
ThreadStackHelper::Shutdown();
}
BackgroundHangMonitor::BackgroundHangMonitor(const char* aName,