author | Jim Chen <nchen@mozilla.com> |
Fri, 22 Nov 2013 14:17:31 -0500 | |
changeset 157081 | c32c0526e7b56e40eb2d4cab666a9634850039e6 |
parent 157080 | c4834a9ec4c8eaaf2c92df6e0fb0f37ff9744025 |
child 157082 | 4c31b0875e214c33a4abce64b9e8e27d2ef135f6 |
push id | 36633 |
push user | nchen@mozilla.com |
push date | Fri, 22 Nov 2013 19:20:41 +0000 |
treeherder | mozilla-inbound@5365478bdea9 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | vladan |
bugs | 932865 |
milestone | 28.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
|
--- a/toolkit/components/telemetry/Telemetry.cpp +++ b/toolkit/components/telemetry/Telemetry.cpp @@ -41,16 +41,17 @@ #include "nsHashKeys.h" #include "nsBaseHashtable.h" #include "nsXULAppAPI.h" #include "nsThreadUtils.h" #include "nsNetCID.h" #include "nsNetUtil.h" #include "plstr.h" #include "nsAppDirectoryServiceDefs.h" +#include "mozilla/ThreadHangStats.h" #include "mozilla/ProcessedStack.h" #include "mozilla/Mutex.h" #include "mozilla/FileUtils.h" #include "mozilla/Preferences.h" #include "mozilla/PoisonIOInterposer.h" #if defined(MOZ_ENABLE_PROFILER_SPS) #include "shared-libraries.h" #endif @@ -243,16 +244,17 @@ public: static already_AddRefed<nsITelemetry> CreateTelemetryInstance(); static void ShutdownTelemetry(); static void RecordSlowStatement(const nsACString &sql, const nsACString &dbName, uint32_t delay); #if defined(MOZ_ENABLE_PROFILER_SPS) static void RecordChromeHang(uint32_t duration, Telemetry::ProcessedStack &aStack); #endif + static void RecordThreadHangStats(Telemetry::ThreadHangStats& aStats); static nsresult GetHistogramEnumId(const char *name, Telemetry::ID *id); static int64_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf); struct Stat { uint32_t hitCount; uint32_t totalTime; }; struct StmtStats { struct Stat mainThread; @@ -315,16 +317,19 @@ private: AutoHashtable<SlowSQLEntryType> mPrivateSQL; AutoHashtable<SlowSQLEntryType> mSanitizedSQL; // This gets marked immutable in debug builds, so we can't use // AutoHashtable here. nsTHashtable<nsCStringHashKey> mTrackedDBs; Mutex mHashMutex; HangReports mHangReports; Mutex mHangReportsMutex; + // mThreadHangStats stores recorded, inactive thread hang stats + Vector<Telemetry::ThreadHangStats> mThreadHangStats; + Mutex mThreadHangStatsMutex; nsCOMPtr<nsIMemoryReporter> mReporter; CombinedStacks mLateWritesStacks; // This is collected out of the main thread. bool mCachedTelemetryData; uint32_t mLastShutdownTime; uint32_t mFailedLockCount; nsCOMArray<nsIFetchTelemetryDataCallback> mCallbacks; friend class nsFetchTelemetryData; @@ -338,16 +343,17 @@ TelemetryImpl::SizeOfIncludingThisHelper size_t n = aMallocSizeOf(this); // Ignore the hashtables in mAddonMap; they are not significant. n += mAddonMap.SizeOfExcludingThis(nullptr, aMallocSizeOf); n += mHistogramMap.SizeOfExcludingThis(nullptr, aMallocSizeOf); n += mPrivateSQL.SizeOfExcludingThis(nullptr, aMallocSizeOf); n += mSanitizedSQL.SizeOfExcludingThis(nullptr, aMallocSizeOf); n += mTrackedDBs.SizeOfExcludingThis(nullptr, aMallocSizeOf); n += mHangReports.SizeOfExcludingThis(); + n += mThreadHangStats.sizeOfExcludingThis(aMallocSizeOf); return n; } int64_t TelemetryImpl::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) { int64_t n = 0; if (sTelemetry) { @@ -936,16 +942,17 @@ TelemetryImpl::AsyncFetchTelemetryData(n return NS_OK; } TelemetryImpl::TelemetryImpl(): mHistogramMap(Telemetry::HistogramCount), mCanRecord(XRE_GetProcessType() == GeckoProcessType_Default), mHashMutex("Telemetry::mHashMutex"), mHangReportsMutex("Telemetry::mHangReportsMutex"), +mThreadHangStatsMutex("Telemetry::mThreadHangStatsMutex"), mCachedTelemetryData(false), mLastShutdownTime(0), mFailedLockCount(0) { // A whitelist to prevent Telemetry reporting on Addon & Thunderbird DBs const char *trackedDBs[] = { "addons.sqlite", "content-prefs.sqlite", "cookies.sqlite", "downloads.sqlite", "extensions.sqlite", "formhistory.sqlite", @@ -2054,16 +2061,27 @@ TelemetryImpl::RecordChromeHang(uint32_t return; MutexAutoLock hangReportMutex(sTelemetry->mHangReportsMutex); sTelemetry->mHangReports.AddHang(aStack, duration); } #endif +void +TelemetryImpl::RecordThreadHangStats(Telemetry::ThreadHangStats& aStats) +{ + if (!sTelemetry || !sTelemetry->mCanRecord) + return; + + MutexAutoLock autoLock(sTelemetry->mThreadHangStatsMutex); + + sTelemetry->mThreadHangStats.append(Move(aStats)); +} + NS_IMPL_ISUPPORTS1(TelemetryImpl, nsITelemetry) NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsITelemetry, TelemetryImpl::CreateTelemetryInstance) #define NS_TELEMETRY_CID \ {0xaea477f2, 0xb3a2, 0x469c, {0xaa, 0x29, 0x0a, 0x82, 0xd1, 0x32, 0xb8, 0x29}} NS_DEFINE_NAMED_CID(NS_TELEMETRY_CID); const Module::CIDEntry kTelemetryCIDs[] = { @@ -2219,16 +2237,21 @@ void Init() #if defined(MOZ_ENABLE_PROFILER_SPS) void RecordChromeHang(uint32_t duration, ProcessedStack &aStack) { TelemetryImpl::RecordChromeHang(duration, aStack); } #endif +void RecordThreadHangStats(ThreadHangStats& aStats) +{ + TelemetryImpl::RecordThreadHangStats(aStats); +} + ProcessedStack::ProcessedStack() { } size_t ProcessedStack::GetStackSize() const { return mStack.size(); }
--- a/toolkit/components/telemetry/Telemetry.h +++ b/toolkit/components/telemetry/Telemetry.h @@ -170,16 +170,30 @@ class ProcessedStack; * @param callStack - Array of PCs from the hung call stack * @param moduleMap - Array of info about modules in memory (for symbolication) */ #if defined(MOZ_ENABLE_PROFILER_SPS) void RecordChromeHang(uint32_t duration, ProcessedStack &aStack); #endif +class ThreadHangStats; + +/** + * Move a ThreadHangStats to Telemetry storage. Normally Telemetry queries + * for active ThreadHangStats through BackgroundHangMonitor, but once a + * thread exits, the thread's copy of ThreadHangStats needs to be moved to + * inside Telemetry using this function. + * + * @param aStats ThreadHangStats to save; the data inside aStats + * will be moved and aStats should be treated as + * invalid after this function returns + */ +void RecordThreadHangStats(ThreadHangStats& aStats); + /** * Record a failed attempt at locking the user's profile. * * @param aProfileDir The profile directory whose lock attempt failed */ void WriteFailedProfileLock(nsIFile* aProfileDir); } // namespace Telemetry
--- a/xpcom/threads/BackgroundHangMonitor.cpp +++ b/xpcom/threads/BackgroundHangMonitor.cpp @@ -2,16 +2,17 @@ /* 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/. */ #include "mozilla/BackgroundHangMonitor.h" #include "mozilla/LinkedList.h" #include "mozilla/Monitor.h" #include "mozilla/StaticPtr.h" +#include "mozilla/Telemetry.h" #include "mozilla/ThreadHangStats.h" #include "mozilla/ThreadLocal.h" #include "prinrval.h" #include "prthread.h" #include <algorithm> @@ -320,16 +321,19 @@ BackgroundHangThread::~BackgroundHangThr remove(); // Wake up monitor thread to process removed thread autoLock.Notify(); // We no longer have a thread if (sTlsKey.initialized()) { sTlsKey.set(nullptr); } + + // Move our copy of ThreadHangStats to Telemetry storage + Telemetry::RecordThreadHangStats(mStats); } void BackgroundHangThread::ReportHang(PRIntervalTime aHangTime) const { // Recovered from a hang; called on the monitor thread // mManager->mLock IS locked