author | Jim Chen <nchen@mozilla.com> |
Fri, 22 Nov 2013 14:17:30 -0500 | |
changeset 157077 | eae56986faba12e48c928da9dc7b3147c242c271 |
parent 157076 | 1cd4e62f97c11f33d7b5905ae208ede1be82d15a |
child 157078 | 18ba8691786d4ce7ccde7ecd00f33ccb633f49dc |
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 @@ -8,16 +8,17 @@ #include <fstream> #include <prio.h> #include "mozilla/Attributes.h" #include "mozilla/DebugOnly.h" #include "mozilla/Likely.h" +#include "mozilla/MathAlgorithms.h" #include "base/histogram.h" #include "base/pickle.h" #include "nsIComponentManager.h" #include "nsIServiceManager.h" #include "nsThreadManager.h" #include "nsCOMArray.h" #include "nsCOMPtr.h" @@ -2434,16 +2435,51 @@ WriteFailedProfileLock(nsIFile* aProfile break; } bytes += written; bytesLeft -= written; } while (bytesLeft > 0); seekStream->SetEOF(); } + +void +TimeHistogram::Add(PRIntervalTime aTime) +{ + uint32_t timeMs = PR_IntervalToMilliseconds(aTime); + size_t index = mozilla::FloorLog2(timeMs); + operator[](index)++; +} + +uint32_t +HangHistogram::GetHash(const Stack& aStack) +{ + uint32_t hash = 0; + for (const char* const* label = aStack.begin(); + label != aStack.end(); label++) { + /* We only need to hash the pointer instead of the text content + because we are assuming constant pointers */ + hash = AddToHash(hash, *label); + } + return hash; +} + +bool +HangHistogram::operator==(const HangHistogram& aOther) const +{ + if (mHash != aOther.mHash) { + return false; + } + if (mStack.length() != aOther.mStack.length()) { + return false; + } + return PodEqual(mStack.begin(), aOther.mStack.begin(), mStack.length()); +} + + } // namespace Telemetry } // namespace mozilla NSMODULE_DEFN(nsTelemetryModule) = &kTelemetryModule; /** * The XRE_TelemetryAdd function is to be used by embedding applications * that can't use mozilla::Telemetry::Accumulate() directly.
new file mode 100644 --- /dev/null +++ b/toolkit/components/telemetry/ThreadHangStats.h @@ -0,0 +1,102 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */ +/* 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/. */ + +#ifndef mozilla_BackgroundHangTelemetry_h +#define mozilla_BackgroundHangTelemetry_h + +#include "mozilla/Array.h" +#include "mozilla/Move.h" +#include "mozilla/Mutex.h" +#include "mozilla/PodOperations.h" +#include "mozilla/Vector.h" + +#include "nsString.h" +#include "prinrval.h" + +namespace mozilla { +namespace Telemetry { + +static const size_t kTimeHistogramBuckets = 8 * sizeof(PRIntervalTime); + +/* TimeHistogram is an efficient histogram that puts time durations into + exponential (base 2) buckets; times are accepted in PRIntervalTime and + stored in milliseconds. */ +class TimeHistogram : public mozilla::Array<uint32_t, kTimeHistogramBuckets> +{ +public: + TimeHistogram() + { + mozilla::PodArrayZero(*this); + } + void Add(PRIntervalTime aTime); +}; + +/* A hang histogram consists of a stack associated with the + hang, along with a time histogram of the hang times. */ +class HangHistogram : public TimeHistogram +{ +public: + typedef mozilla::Vector<const char*, 8> Stack; + +private: + static uint32_t GetHash(const Stack& aStack); + + Stack mStack; + // Use a hash to speed comparisons + const uint32_t mHash; + +public: + explicit HangHistogram(Stack&& aStack) + : mStack(mozilla::Move(aStack)) + , mHash(GetHash(mStack)) + { + } + HangHistogram(HangHistogram&& aOther) + : TimeHistogram(mozilla::Move(aOther)) + , mStack(mozilla::Move(aOther.mStack)) + , mHash(mozilla::Move(aOther.mHash)) + { + } + bool operator==(const HangHistogram& aOther) const; + bool operator!=(const HangHistogram& aOther) const + { + return !operator==(aOther); + } + const Stack& GetStack() const { + return mStack; + } +}; + +/* Thread hang stats consist of + - thread name + - time histogram of all task run times + - hang histograms of individual hangs. */ +class ThreadHangStats +{ +private: + nsAutoCString mName; + +public: + TimeHistogram mActivity; + mozilla::Vector<HangHistogram, 4> mHangs; + + explicit ThreadHangStats(const char* aName) + : mName(aName) + { + } + ThreadHangStats(ThreadHangStats&& aOther) + : mName(mozilla::Move(aOther.mName)) + , mActivity(mozilla::Move(aOther.mActivity)) + , mHangs(mozilla::Move(aOther.mHangs)) + { + } + const char* GetName() const { + return mName.get(); + } +}; + +} // namespace Telemetry +} // namespace mozilla +#endif // mozilla_BackgroundHangTelemetry_h
--- a/toolkit/components/telemetry/moz.build +++ b/toolkit/components/telemetry/moz.build @@ -11,16 +11,17 @@ XPIDL_SOURCES += [ 'nsITelemetryPing.idl', ] XPIDL_MODULE = 'telemetry' EXPORTS.mozilla += [ 'ProcessedStack.h', 'Telemetry.h', + 'ThreadHangStats.h', ] SOURCES += [ 'Telemetry.cpp', ] EXTRA_COMPONENTS += [ 'TelemetryPing.manifest',