зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1310880 - Allow a BackgroundHangMonitor to have its own private BackgroundHangThread. r=jchen
MozReview-Commit-ID: L32E19FVhv --HG-- extra : rebase_source : ad279f8a04e2e33a8b37e15674263aa7a1a0efbf extra : histedit_source : 9f085995ec8d39014a45ab06fb366fb52eb57c6c
This commit is contained in:
Родитель
7481809d32
Коммит
f2fa591912
|
@ -141,14 +141,24 @@ private:
|
||||||
// Unique thread ID for identification
|
// Unique thread ID for identification
|
||||||
const PRThread* mThreadID;
|
const PRThread* mThreadID;
|
||||||
|
|
||||||
|
void Update();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NS_INLINE_DECL_REFCOUNTING(BackgroundHangThread)
|
NS_INLINE_DECL_REFCOUNTING(BackgroundHangThread)
|
||||||
|
/**
|
||||||
|
* Returns the BackgroundHangThread associated with the
|
||||||
|
* running thread. Note that this will not find private
|
||||||
|
* BackgroundHangThread threads.
|
||||||
|
*
|
||||||
|
* @return BackgroundHangThread*, or nullptr if no thread
|
||||||
|
* is found.
|
||||||
|
*/
|
||||||
static BackgroundHangThread* FindThread();
|
static BackgroundHangThread* FindThread();
|
||||||
|
|
||||||
static void Startup()
|
static void Startup()
|
||||||
{
|
{
|
||||||
/* We can tolerate init() failing. */
|
/* We can tolerate init() failing. */
|
||||||
(void)!sTlsKey.init();
|
sTlsKeyInitialized = sTlsKey.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hang timeout in ticks
|
// Hang timeout in ticks
|
||||||
|
@ -163,6 +173,8 @@ public:
|
||||||
bool mHanging;
|
bool mHanging;
|
||||||
// Is the thread in a waiting state
|
// Is the thread in a waiting state
|
||||||
bool mWaiting;
|
bool mWaiting;
|
||||||
|
// Is the thread dedicated to a single BackgroundHangMonitor
|
||||||
|
BackgroundHangMonitor::ThreadType mThreadType;
|
||||||
// Platform-specific helper to get hang stacks
|
// Platform-specific helper to get hang stacks
|
||||||
ThreadStackHelper mStackHelper;
|
ThreadStackHelper mStackHelper;
|
||||||
// Stack of current hang
|
// Stack of current hang
|
||||||
|
@ -176,20 +188,32 @@ public:
|
||||||
|
|
||||||
BackgroundHangThread(const char* aName,
|
BackgroundHangThread(const char* aName,
|
||||||
uint32_t aTimeoutMs,
|
uint32_t aTimeoutMs,
|
||||||
uint32_t aMaxTimeoutMs);
|
uint32_t aMaxTimeoutMs,
|
||||||
|
BackgroundHangMonitor::ThreadType aThreadType = BackgroundHangMonitor::THREAD_SHARED);
|
||||||
|
|
||||||
// Report a hang; aManager->mLock IS locked
|
// Report a hang; aManager->mLock IS locked
|
||||||
Telemetry::HangHistogram& ReportHang(PRIntervalTime aHangTime);
|
Telemetry::HangHistogram& ReportHang(PRIntervalTime aHangTime);
|
||||||
// Report a permanent hang; aManager->mLock IS locked
|
// Report a permanent hang; aManager->mLock IS locked
|
||||||
void ReportPermaHang();
|
void ReportPermaHang();
|
||||||
// Called by BackgroundHangMonitor::NotifyActivity
|
// Called by BackgroundHangMonitor::NotifyActivity
|
||||||
void NotifyActivity();
|
void NotifyActivity()
|
||||||
|
{
|
||||||
|
MonitorAutoLock autoLock(mManager->mLock);
|
||||||
|
Update();
|
||||||
|
}
|
||||||
// Called by BackgroundHangMonitor::NotifyWait
|
// Called by BackgroundHangMonitor::NotifyWait
|
||||||
void NotifyWait()
|
void NotifyWait()
|
||||||
{
|
{
|
||||||
NotifyActivity();
|
MonitorAutoLock autoLock(mManager->mLock);
|
||||||
|
Update();
|
||||||
mWaiting = true;
|
mWaiting = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns true if this thread is (or might be) shared between other
|
||||||
|
// BackgroundHangMonitors for the monitored thread.
|
||||||
|
bool IsShared() {
|
||||||
|
return mThreadType == BackgroundHangMonitor::THREAD_SHARED;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -347,7 +371,8 @@ BackgroundHangManager::RunMonitorThread()
|
||||||
|
|
||||||
BackgroundHangThread::BackgroundHangThread(const char* aName,
|
BackgroundHangThread::BackgroundHangThread(const char* aName,
|
||||||
uint32_t aTimeoutMs,
|
uint32_t aTimeoutMs,
|
||||||
uint32_t aMaxTimeoutMs)
|
uint32_t aMaxTimeoutMs,
|
||||||
|
BackgroundHangMonitor::ThreadType aThreadType)
|
||||||
: mManager(BackgroundHangManager::sInstance)
|
: mManager(BackgroundHangManager::sInstance)
|
||||||
, mThreadID(PR_GetCurrentThread())
|
, mThreadID(PR_GetCurrentThread())
|
||||||
, mTimeout(aTimeoutMs == BackgroundHangMonitor::kNoTimeout
|
, mTimeout(aTimeoutMs == BackgroundHangMonitor::kNoTimeout
|
||||||
|
@ -360,9 +385,10 @@ BackgroundHangThread::BackgroundHangThread(const char* aName,
|
||||||
, mHangStart(mInterval)
|
, mHangStart(mInterval)
|
||||||
, mHanging(false)
|
, mHanging(false)
|
||||||
, mWaiting(true)
|
, mWaiting(true)
|
||||||
|
, mThreadType(aThreadType)
|
||||||
, mStats(aName)
|
, mStats(aName)
|
||||||
{
|
{
|
||||||
if (sTlsKeyInitialized) {
|
if (sTlsKeyInitialized && IsShared()) {
|
||||||
sTlsKey.set(this);
|
sTlsKey.set(this);
|
||||||
}
|
}
|
||||||
// Lock here because LinkedList is not thread-safe
|
// Lock here because LinkedList is not thread-safe
|
||||||
|
@ -383,7 +409,7 @@ BackgroundHangThread::~BackgroundHangThread()
|
||||||
autoLock.Notify();
|
autoLock.Notify();
|
||||||
|
|
||||||
// We no longer have a thread
|
// We no longer have a thread
|
||||||
if (sTlsKeyInitialized) {
|
if (sTlsKeyInitialized && IsShared()) {
|
||||||
sTlsKey.set(nullptr);
|
sTlsKey.set(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -452,7 +478,7 @@ BackgroundHangThread::ReportPermaHang()
|
||||||
}
|
}
|
||||||
|
|
||||||
MOZ_ALWAYS_INLINE void
|
MOZ_ALWAYS_INLINE void
|
||||||
BackgroundHangThread::NotifyActivity()
|
BackgroundHangThread::Update()
|
||||||
{
|
{
|
||||||
PRIntervalTime intervalNow = mManager->mIntervalNow;
|
PRIntervalTime intervalNow = mManager->mIntervalNow;
|
||||||
if (mWaiting) {
|
if (mWaiting) {
|
||||||
|
@ -495,7 +521,7 @@ BackgroundHangThread::FindThread()
|
||||||
MonitorAutoLock autoLock(manager->mLock);
|
MonitorAutoLock autoLock(manager->mLock);
|
||||||
for (BackgroundHangThread* thread = manager->mHangThreads.getFirst();
|
for (BackgroundHangThread* thread = manager->mHangThreads.getFirst();
|
||||||
thread; thread = thread->getNext()) {
|
thread; thread = thread->getNext()) {
|
||||||
if (thread->mThreadID == threadID) {
|
if (thread->mThreadID == threadID && thread->IsShared()) {
|
||||||
return thread;
|
return thread;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -587,12 +613,14 @@ BackgroundHangMonitor::Shutdown()
|
||||||
|
|
||||||
BackgroundHangMonitor::BackgroundHangMonitor(const char* aName,
|
BackgroundHangMonitor::BackgroundHangMonitor(const char* aName,
|
||||||
uint32_t aTimeoutMs,
|
uint32_t aTimeoutMs,
|
||||||
uint32_t aMaxTimeoutMs)
|
uint32_t aMaxTimeoutMs,
|
||||||
: mThread(BackgroundHangThread::FindThread())
|
ThreadType aThreadType)
|
||||||
|
: mThread(aThreadType == THREAD_SHARED ? BackgroundHangThread::FindThread() : nullptr)
|
||||||
{
|
{
|
||||||
#ifdef MOZ_ENABLE_BACKGROUND_HANG_MONITOR
|
#ifdef MOZ_ENABLE_BACKGROUND_HANG_MONITOR
|
||||||
if (!BackgroundHangManager::sDisabled && !mThread) {
|
if (!BackgroundHangManager::sDisabled && !mThread) {
|
||||||
mThread = new BackgroundHangThread(aName, aTimeoutMs, aMaxTimeoutMs);
|
mThread = new BackgroundHangThread(aName, aTimeoutMs, aMaxTimeoutMs,
|
||||||
|
aThreadType);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,6 +116,16 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static const uint32_t kNoTimeout = 0;
|
static const uint32_t kNoTimeout = 0;
|
||||||
|
enum ThreadType {
|
||||||
|
// For a new BackgroundHangMonitor for thread T, only create a new
|
||||||
|
// monitoring thread for T if one doesn't already exist. If one does,
|
||||||
|
// share that pre-existing monitoring thread.
|
||||||
|
THREAD_SHARED,
|
||||||
|
// For a new BackgroundHangMonitor for thread T, create a new
|
||||||
|
// monitoring thread for T even if there are other, pre-existing
|
||||||
|
// monitoring threads for T.
|
||||||
|
THREAD_PRIVATE
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ThreadHangStatsIterator is used to iterate through the ThreadHangStats
|
* ThreadHangStatsIterator is used to iterate through the ThreadHangStats
|
||||||
|
@ -180,10 +190,14 @@ public:
|
||||||
* activity before registering a hang
|
* activity before registering a hang
|
||||||
* @param aMaxTimeoutMs Amount of time in milliseconds without
|
* @param aMaxTimeoutMs Amount of time in milliseconds without
|
||||||
* activity before registering a permanent hang
|
* activity before registering a permanent hang
|
||||||
|
* @param aThreadType
|
||||||
|
* The ThreadType type of monitoring thread that should be created
|
||||||
|
* for this monitor. See the documentation for ThreadType.
|
||||||
*/
|
*/
|
||||||
BackgroundHangMonitor(const char* aName,
|
BackgroundHangMonitor(const char* aName,
|
||||||
uint32_t aTimeoutMs,
|
uint32_t aTimeoutMs,
|
||||||
uint32_t aMaxTimeoutMs);
|
uint32_t aMaxTimeoutMs,
|
||||||
|
ThreadType aThreadType = THREAD_SHARED);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Monitor hangs using an existing monitor
|
* Monitor hangs using an existing monitor
|
||||||
|
|
Загрузка…
Ссылка в новой задаче