mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 932865 - Add way for telemetry to iterate over active threads; r=froydnj
This commit is contained in:
parent
8a6972b958
commit
4b4ea979e2
@ -7,6 +7,7 @@
|
|||||||
#include "mozilla/LinkedList.h"
|
#include "mozilla/LinkedList.h"
|
||||||
#include "mozilla/Monitor.h"
|
#include "mozilla/Monitor.h"
|
||||||
#include "mozilla/StaticPtr.h"
|
#include "mozilla/StaticPtr.h"
|
||||||
|
#include "mozilla/ThreadHangStats.h"
|
||||||
#include "mozilla/ThreadLocal.h"
|
#include "mozilla/ThreadLocal.h"
|
||||||
|
|
||||||
#include "prinrval.h"
|
#include "prinrval.h"
|
||||||
@ -103,8 +104,6 @@ public:
|
|||||||
if (!sTlsKey.init()) {}
|
if (!sTlsKey.init()) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Name of the thread
|
|
||||||
const nsAutoCString mThreadName;
|
|
||||||
// Hang timeout in ticks
|
// Hang timeout in ticks
|
||||||
const PRIntervalTime mTimeout;
|
const PRIntervalTime mTimeout;
|
||||||
// PermaHang timeout in ticks
|
// PermaHang timeout in ticks
|
||||||
@ -117,6 +116,8 @@ public:
|
|||||||
bool mHanging;
|
bool mHanging;
|
||||||
// Is the thread in a waiting state
|
// Is the thread in a waiting state
|
||||||
bool mWaiting;
|
bool mWaiting;
|
||||||
|
// Statistics for telemetry
|
||||||
|
Telemetry::ThreadHangStats mStats;
|
||||||
|
|
||||||
BackgroundHangThread(const char* aName,
|
BackgroundHangThread(const char* aName,
|
||||||
uint32_t aTimeoutMs,
|
uint32_t aTimeoutMs,
|
||||||
@ -292,13 +293,13 @@ BackgroundHangThread::BackgroundHangThread(const char* aName,
|
|||||||
uint32_t aMaxTimeoutMs)
|
uint32_t aMaxTimeoutMs)
|
||||||
: mManager(BackgroundHangManager::sInstance)
|
: mManager(BackgroundHangManager::sInstance)
|
||||||
, mThreadID(PR_GetCurrentThread())
|
, mThreadID(PR_GetCurrentThread())
|
||||||
, mThreadName(aName)
|
|
||||||
, mTimeout(PR_MillisecondsToInterval(aTimeoutMs))
|
, mTimeout(PR_MillisecondsToInterval(aTimeoutMs))
|
||||||
, mMaxTimeout(PR_MillisecondsToInterval(aMaxTimeoutMs))
|
, mMaxTimeout(PR_MillisecondsToInterval(aMaxTimeoutMs))
|
||||||
, mInterval(mManager->mIntervalNow)
|
, mInterval(mManager->mIntervalNow)
|
||||||
, mHangStart(mInterval)
|
, mHangStart(mInterval)
|
||||||
, mHanging(false)
|
, mHanging(false)
|
||||||
, mWaiting(true)
|
, mWaiting(true)
|
||||||
|
, mStats(aName)
|
||||||
{
|
{
|
||||||
if (sTlsKey.initialized()) {
|
if (sTlsKey.initialized()) {
|
||||||
sTlsKey.set(this);
|
sTlsKey.set(this);
|
||||||
@ -440,4 +441,25 @@ BackgroundHangMonitor::NotifyWait()
|
|||||||
mThread->NotifyWait();
|
mThread->NotifyWait();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 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->mHangThreads.getFirst())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Telemetry::ThreadHangStats*
|
||||||
|
BackgroundHangMonitor::ThreadHangStatsIterator::GetNext()
|
||||||
|
{
|
||||||
|
if (!mThread) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
Telemetry::ThreadHangStats* stats = &mThread->mStats;
|
||||||
|
mThread = mThread->getNext();
|
||||||
|
return stats;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
@ -7,11 +7,16 @@
|
|||||||
#define mozilla_BackgroundHangMonitor_h
|
#define mozilla_BackgroundHangMonitor_h
|
||||||
|
|
||||||
#include "mozilla/RefPtr.h"
|
#include "mozilla/RefPtr.h"
|
||||||
|
#include "mozilla/Monitor.h"
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
|
namespace Telemetry {
|
||||||
|
class ThreadHangStats;
|
||||||
|
};
|
||||||
|
|
||||||
class BackgroundHangThread;
|
class BackgroundHangThread;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -101,6 +106,44 @@ private:
|
|||||||
RefPtr<BackgroundHangThread> mThread;
|
RefPtr<BackgroundHangThread> mThread;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* ThreadHangStatsIterator is used to iterate through the ThreadHangStats
|
||||||
|
* associated with each active monitored thread. Because of an internal
|
||||||
|
* lock while this object is alive, a thread must use only one instance
|
||||||
|
* of this class at a time and must iterate through the list as fast as
|
||||||
|
* possible. The following example shows using the iterator:
|
||||||
|
*
|
||||||
|
* {
|
||||||
|
* // Scope the iter variable so it's destroyed as soon as we're done
|
||||||
|
* BackgroundHangMonitor::ThreadHangStatsIterator iter;
|
||||||
|
* for (ThreadHangStats* histogram = iter.GetNext();
|
||||||
|
* histogram; histogram = iter.GetNext()) {
|
||||||
|
* // Process histogram
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
class ThreadHangStatsIterator : public MonitorAutoLock
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
BackgroundHangThread* mThread;
|
||||||
|
|
||||||
|
ThreadHangStatsIterator(const ThreadHangStatsIterator&);
|
||||||
|
ThreadHangStatsIterator& operator=(const ThreadHangStatsIterator&);
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Create an ThreadHangStatsIterator instance and take the internal lock.
|
||||||
|
* Internal lock is released on destruction.
|
||||||
|
*/
|
||||||
|
ThreadHangStatsIterator();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the next item in the list; the first call returns the first item.
|
||||||
|
* Returns nullptr at the end of the list.
|
||||||
|
*/
|
||||||
|
Telemetry::ThreadHangStats* GetNext();
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable hang monitoring.
|
* Enable hang monitoring.
|
||||||
* Must return before using BackgroundHangMonitor.
|
* Must return before using BackgroundHangMonitor.
|
||||||
|
Loading…
Reference in New Issue
Block a user