mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-11 16:32:59 +00:00
Bug 1133521 - Enable BHR on Beta. r=vladan
This commit is contained in:
parent
c4c85779d8
commit
5820c9e446
@ -2911,21 +2911,20 @@ TelemetryImpl::GetThreadHangStats(JSContext* cx, JS::MutableHandle<JS::Value> re
|
||||
}
|
||||
size_t threadIndex = 0;
|
||||
|
||||
#ifdef MOZ_ENABLE_BACKGROUND_HANG_MONITOR
|
||||
/* First add active threads; we need to hold |iter| (and its lock)
|
||||
throughout this method to avoid a race condition where a thread can
|
||||
be recorded twice if the thread is destroyed while this method is
|
||||
running */
|
||||
BackgroundHangMonitor::ThreadHangStatsIterator iter;
|
||||
for (Telemetry::ThreadHangStats* histogram = iter.GetNext();
|
||||
histogram; histogram = iter.GetNext()) {
|
||||
JS::RootedObject obj(cx,
|
||||
CreateJSThreadHangStats(cx, *histogram));
|
||||
if (!JS_DefineElement(cx, retObj, threadIndex++, obj, JSPROP_ENUMERATE)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
if (!BackgroundHangMonitor::IsDisabled()) {
|
||||
/* First add active threads; we need to hold |iter| (and its lock)
|
||||
throughout this method to avoid a race condition where a thread can
|
||||
be recorded twice if the thread is destroyed while this method is
|
||||
running */
|
||||
BackgroundHangMonitor::ThreadHangStatsIterator iter;
|
||||
for (Telemetry::ThreadHangStats* histogram = iter.GetNext();
|
||||
histogram; histogram = iter.GetNext()) {
|
||||
JS::RootedObject obj(cx, CreateJSThreadHangStats(cx, *histogram));
|
||||
if (!JS_DefineElement(cx, retObj, threadIndex++, obj, JSPROP_ENUMERATE)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Add saved threads next
|
||||
MutexAutoLock autoLock(mThreadHangStatsMutex);
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "mozilla/LinkedList.h"
|
||||
#include "mozilla/Monitor.h"
|
||||
#include "mozilla/Move.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "mozilla/ThreadHangStats.h"
|
||||
@ -20,16 +21,23 @@
|
||||
#include "prinrval.h"
|
||||
#include "prthread.h"
|
||||
#include "ThreadStackHelper.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
// Activate BHR only for one every BHR_BETA_MOD users.
|
||||
#define BHR_BETA_MOD 100;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
/**
|
||||
* BackgroundHangManager is the global object that
|
||||
* manages all instances of BackgroundHangThread.
|
||||
*/
|
||||
class BackgroundHangManager
|
||||
class BackgroundHangManager : public nsIObserver
|
||||
{
|
||||
private:
|
||||
// Background hang monitor thread function
|
||||
@ -61,9 +69,11 @@ private:
|
||||
void RunMonitorThread();
|
||||
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(BackgroundHangManager)
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSIOBSERVER
|
||||
static StaticRefPtr<BackgroundHangManager> sInstance;
|
||||
static bool sProhibited;
|
||||
static bool sDisabled;
|
||||
|
||||
// Lock for access to members of this class
|
||||
Monitor mLock;
|
||||
@ -90,9 +100,23 @@ public:
|
||||
|
||||
BackgroundHangManager();
|
||||
private:
|
||||
~BackgroundHangManager();
|
||||
virtual ~BackgroundHangManager();
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(BackgroundHangManager, nsIObserver)
|
||||
|
||||
NS_IMETHODIMP
|
||||
BackgroundHangManager::Observe(nsISupports* aSubject, const char* aTopic, const char16_t* aData) {
|
||||
NS_ENSURE_TRUE(!strcmp(aTopic, "profile-after-change"), NS_ERROR_UNEXPECTED);
|
||||
BackgroundHangMonitor::DisableOnBeta();
|
||||
|
||||
nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService();
|
||||
MOZ_ASSERT(observerService);
|
||||
observerService->RemoveObserver(this, "profile-after-change");
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* BackgroundHangThread is a per-thread object that is used
|
||||
* by all instances of BackgroundHangMonitor to monitor hangs.
|
||||
@ -162,6 +186,7 @@ public:
|
||||
|
||||
StaticRefPtr<BackgroundHangManager> BackgroundHangManager::sInstance;
|
||||
bool BackgroundHangManager::sProhibited = false;
|
||||
bool BackgroundHangManager::sDisabled = false;
|
||||
|
||||
ThreadLocal<BackgroundHangThread*> BackgroundHangThread::sTlsKey;
|
||||
|
||||
@ -421,7 +446,7 @@ BackgroundHangThread::FindThread()
|
||||
{
|
||||
#ifdef MOZ_ENABLE_BACKGROUND_HANG_MONITOR
|
||||
if (BackgroundHangManager::sInstance == nullptr) {
|
||||
MOZ_ASSERT(BackgroundHangManager::sProhibited,
|
||||
MOZ_ASSERT(BackgroundHangManager::sProhibited || BackgroundHangManager::sDisabled,
|
||||
"BackgroundHandleManager is not initialized");
|
||||
return nullptr;
|
||||
}
|
||||
@ -450,6 +475,38 @@ BackgroundHangThread::FindThread()
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
BackgroundHangMonitor::ShouldDisableOnBeta(const nsCString &clientID) {
|
||||
MOZ_ASSERT(clientID.Length() == 36, "clientID is invalid");
|
||||
const char *suffix = clientID.get() + clientID.Length() - 4;
|
||||
return strtol(suffix, NULL, 16) % BHR_BETA_MOD;
|
||||
}
|
||||
|
||||
bool
|
||||
BackgroundHangMonitor::IsDisabled() {
|
||||
#ifdef MOZ_ENABLE_BACKGROUND_HANG_MONITOR
|
||||
return BackgroundHangManager::sDisabled;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
BackgroundHangMonitor::DisableOnBeta() {
|
||||
nsAdoptingCString clientID = Preferences::GetCString("toolkit.telemetry.cachedClientID");
|
||||
bool telemetryEnabled = Preferences::GetBool("toolkit.telemetry.enabled");
|
||||
|
||||
if (!telemetryEnabled || !clientID || BackgroundHangMonitor::ShouldDisableOnBeta(clientID)) {
|
||||
if (XRE_IsParentProcess()) {
|
||||
BackgroundHangMonitor::Shutdown();
|
||||
} else {
|
||||
BackgroundHangManager::sDisabled = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
BackgroundHangMonitor::Startup()
|
||||
@ -457,6 +514,23 @@ BackgroundHangMonitor::Startup()
|
||||
#ifdef MOZ_ENABLE_BACKGROUND_HANG_MONITOR
|
||||
MOZ_ASSERT(!BackgroundHangManager::sProhibited, "Prohibited");
|
||||
MOZ_ASSERT(!BackgroundHangManager::sInstance, "Already initialized");
|
||||
|
||||
if (!strcmp(NS_STRINGIFY(MOZ_UPDATE_CHANNEL), "beta")) {
|
||||
if (XRE_IsParentProcess()) { // cached ClientID hasn't been read yet
|
||||
ThreadStackHelper::Startup();
|
||||
BackgroundHangThread::Startup();
|
||||
BackgroundHangManager::sInstance = new BackgroundHangManager();
|
||||
|
||||
nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService();
|
||||
MOZ_ASSERT(observerService);
|
||||
|
||||
observerService->AddObserver(BackgroundHangManager::sInstance, "profile-after-change", false);
|
||||
return;
|
||||
} else if(DisableOnBeta()){
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ThreadStackHelper::Startup();
|
||||
BackgroundHangThread::Startup();
|
||||
BackgroundHangManager::sInstance = new BackgroundHangManager();
|
||||
@ -467,6 +541,11 @@ void
|
||||
BackgroundHangMonitor::Shutdown()
|
||||
{
|
||||
#ifdef MOZ_ENABLE_BACKGROUND_HANG_MONITOR
|
||||
if (BackgroundHangManager::sDisabled) {
|
||||
MOZ_ASSERT(!BackgroundHangManager::sInstance, "Initialized");
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!BackgroundHangManager::sProhibited, "Prohibited");
|
||||
MOZ_ASSERT(BackgroundHangManager::sInstance, "Not initialized");
|
||||
/* Scope our lock inside Shutdown() because the sInstance object can
|
||||
@ -475,6 +554,7 @@ BackgroundHangMonitor::Shutdown()
|
||||
BackgroundHangManager::sInstance->Shutdown();
|
||||
BackgroundHangManager::sInstance = nullptr;
|
||||
ThreadStackHelper::Shutdown();
|
||||
BackgroundHangManager::sDisabled = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -484,7 +564,7 @@ BackgroundHangMonitor::BackgroundHangMonitor(const char* aName,
|
||||
: mThread(BackgroundHangThread::FindThread())
|
||||
{
|
||||
#ifdef MOZ_ENABLE_BACKGROUND_HANG_MONITOR
|
||||
if (!BackgroundHangManager::sProhibited && !mThread) {
|
||||
if (!BackgroundHangManager::sDisabled && !BackgroundHangManager::sProhibited && !mThread) {
|
||||
// If sProhibit is true, mThread would be null, and no monitoring.
|
||||
mThread = new BackgroundHangThread(aName, aTimeoutMs, aMaxTimeoutMs);
|
||||
}
|
||||
@ -495,6 +575,10 @@ BackgroundHangMonitor::BackgroundHangMonitor()
|
||||
: mThread(BackgroundHangThread::FindThread())
|
||||
{
|
||||
#ifdef MOZ_ENABLE_BACKGROUND_HANG_MONITOR
|
||||
if (BackgroundHangManager::sDisabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!BackgroundHangManager::sProhibited || mThread,
|
||||
"This thread is not initialized for hang monitoring");
|
||||
#endif
|
||||
@ -509,7 +593,8 @@ BackgroundHangMonitor::NotifyActivity()
|
||||
{
|
||||
#ifdef MOZ_ENABLE_BACKGROUND_HANG_MONITOR
|
||||
if (mThread == nullptr) {
|
||||
MOZ_ASSERT(BackgroundHangManager::sProhibited,
|
||||
MOZ_ASSERT(BackgroundHangManager::sProhibited ||
|
||||
BackgroundHangManager::sDisabled,
|
||||
"This thread is not initialized for hang monitoring");
|
||||
return;
|
||||
}
|
||||
@ -525,7 +610,8 @@ BackgroundHangMonitor::NotifyWait()
|
||||
{
|
||||
#ifdef MOZ_ENABLE_BACKGROUND_HANG_MONITOR
|
||||
if (mThread == nullptr) {
|
||||
MOZ_ASSERT(BackgroundHangManager::sProhibited,
|
||||
MOZ_ASSERT(BackgroundHangManager::sProhibited ||
|
||||
BackgroundHangManager::sDisabled,
|
||||
"This thread is not initialized for hang monitoring");
|
||||
return;
|
||||
}
|
||||
@ -567,7 +653,9 @@ BackgroundHangMonitor::ThreadHangStatsIterator::ThreadHangStatsIterator()
|
||||
nullptr)
|
||||
{
|
||||
#ifdef MOZ_ENABLE_BACKGROUND_HANG_MONITOR
|
||||
MOZ_ASSERT(BackgroundHangManager::sInstance || BackgroundHangManager::sProhibited,
|
||||
MOZ_ASSERT(BackgroundHangManager::sInstance ||
|
||||
BackgroundHangManager::sProhibited ||
|
||||
BackgroundHangManager::sDisabled,
|
||||
"Inconsistent state");
|
||||
#endif
|
||||
}
|
||||
|
@ -10,6 +10,8 @@
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/Monitor.h"
|
||||
|
||||
#include "nsString.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace mozilla {
|
||||
@ -18,14 +20,8 @@ namespace Telemetry {
|
||||
class ThreadHangStats;
|
||||
};
|
||||
|
||||
// Disabled for Beta/Release builds because of bug 965392.
|
||||
// Disabled for debug builds because of bug 979069.
|
||||
#if !defined(RELEASE_BUILD) && !defined(DEBUG)
|
||||
// Undefine to disable background hang monitor
|
||||
#define MOZ_ENABLE_BACKGROUND_HANG_MONITOR
|
||||
#endif
|
||||
|
||||
class BackgroundHangThread;
|
||||
class BackgroundHangManager;
|
||||
|
||||
/**
|
||||
* The background hang monitor is responsible for detecting and reporting
|
||||
@ -113,8 +109,13 @@ class BackgroundHangThread;
|
||||
class BackgroundHangMonitor
|
||||
{
|
||||
private:
|
||||
friend BackgroundHangManager;
|
||||
|
||||
RefPtr<BackgroundHangThread> mThread;
|
||||
|
||||
static bool ShouldDisableOnBeta(const nsCString &);
|
||||
static bool DisableOnBeta();
|
||||
|
||||
public:
|
||||
static const uint32_t kNoTimeout = 0;
|
||||
|
||||
@ -168,6 +169,11 @@ public:
|
||||
*/
|
||||
static void Shutdown();
|
||||
|
||||
/**
|
||||
* Returns true if BHR is disabled.
|
||||
*/
|
||||
static bool IsDisabled();
|
||||
|
||||
/**
|
||||
* Start monitoring hangs for the current thread.
|
||||
*
|
||||
|
@ -59,6 +59,11 @@ LOCAL_INCLUDES += [
|
||||
'/tools/profiler',
|
||||
]
|
||||
|
||||
# BHR disabled for Release builds because of bug 965392.
|
||||
# BHR disabled for debug builds because of bug 979069.
|
||||
if CONFIG['MOZ_UPDATE_CHANNEL'] not in ('release') and not CONFIG['MOZ_DEBUG']:
|
||||
DEFINES['MOZ_ENABLE_BACKGROUND_HANG_MONITOR'] = 1
|
||||
|
||||
FAIL_ON_WARNINGS = True
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
Loading…
Reference in New Issue
Block a user