mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-13 05:15:45 +00:00
bug 1218576 - Accumulate child histograms in the parent process r=froydnj
Batch the accumulations to only transmit every so often, so we don't incur too much in the way of IPC overhead penalties. What this doesn't do: * remove or restructure child telemetry code to adapt to the new way * send the telemetry anywhere * allow for the child process to clear child histograms * support anything but histograms (but this is expected and okay) MozReview-Commit-ID: JnUkcmN3Ya7
This commit is contained in:
parent
c0e2f75813
commit
7876f2ef1e
@ -5413,3 +5413,19 @@ ContentParent::ForceTabPaint(TabParent* aTabParent, uint64_t aLayerObserverEpoch
|
|||||||
}
|
}
|
||||||
ProcessHangMonitor::ForcePaint(mHangMonitorActor, aTabParent, aLayerObserverEpoch);
|
ProcessHangMonitor::ForcePaint(mHangMonitorActor, aTabParent, aLayerObserverEpoch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ContentParent::RecvAccumulateChildHistogram(
|
||||||
|
InfallibleTArray<Accumulation>&& aAccumulations)
|
||||||
|
{
|
||||||
|
Telemetry::AccumulateChild(aAccumulations);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ContentParent::RecvAccumulateChildKeyedHistogram(
|
||||||
|
InfallibleTArray<KeyedAccumulation>&& aAccumulations)
|
||||||
|
{
|
||||||
|
Telemetry::AccumulateChildKeyed(aAccumulations);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@ -1137,6 +1137,10 @@ private:
|
|||||||
|
|
||||||
virtual bool RecvDeleteGetFilesRequest(const nsID& aID) override;
|
virtual bool RecvDeleteGetFilesRequest(const nsID& aID) override;
|
||||||
|
|
||||||
|
virtual bool RecvAccumulateChildHistogram(
|
||||||
|
InfallibleTArray<Accumulation>&& aAccumulations) override;
|
||||||
|
virtual bool RecvAccumulateChildKeyedHistogram(
|
||||||
|
InfallibleTArray<KeyedAccumulation>&& aAccumulations) override;
|
||||||
public:
|
public:
|
||||||
void SendGetFilesResponseAndForget(const nsID& aID,
|
void SendGetFilesResponseAndForget(const nsID& aID,
|
||||||
const GetFilesResponseResult& aResult);
|
const GetFilesResponseResult& aResult);
|
||||||
|
@ -100,6 +100,8 @@ using mozilla::DataStorageType from "ipc/DataStorageIPCUtils.h";
|
|||||||
using mozilla::DocShellOriginAttributes from "mozilla/ipc/BackgroundUtils.h";
|
using mozilla::DocShellOriginAttributes from "mozilla/ipc/BackgroundUtils.h";
|
||||||
using struct mozilla::layers::TextureFactoryIdentifier from "mozilla/layers/CompositorTypes.h";
|
using struct mozilla::layers::TextureFactoryIdentifier from "mozilla/layers/CompositorTypes.h";
|
||||||
using struct mozilla::dom::FlyWebPublishOptions from "mozilla/dom/FlyWebPublishOptionsIPCSerializer.h";
|
using struct mozilla::dom::FlyWebPublishOptions from "mozilla/dom/FlyWebPublishOptionsIPCSerializer.h";
|
||||||
|
using mozilla::Telemetry::Accumulation from "mozilla/TelemetryComms.h";
|
||||||
|
using mozilla::Telemetry::KeyedAccumulation from "mozilla/TelemetryComms.h";
|
||||||
|
|
||||||
union ChromeRegistryItem
|
union ChromeRegistryItem
|
||||||
{
|
{
|
||||||
@ -1216,6 +1218,12 @@ parent:
|
|||||||
|
|
||||||
async UnstoreAndBroadcastBlobURLUnregistration(nsCString url);
|
async UnstoreAndBroadcastBlobURLUnregistration(nsCString url);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Messages for communicating child Telemetry to the parent process
|
||||||
|
*/
|
||||||
|
async AccumulateChildHistogram(Accumulation[] accumulations);
|
||||||
|
async AccumulateChildKeyedHistogram(KeyedAccumulation[] accumulations);
|
||||||
|
|
||||||
both:
|
both:
|
||||||
async AsyncMessage(nsString aMessage, CpowEntry[] aCpows,
|
async AsyncMessage(nsString aMessage, CpowEntry[] aCpows,
|
||||||
Principal aPrincipal, ClonedMessageData aData);
|
Principal aPrincipal, ClonedMessageData aData);
|
||||||
|
@ -2793,6 +2793,18 @@ AccumulateTimeDelta(ID aHistogram, TimeStamp start, TimeStamp end)
|
|||||||
static_cast<uint32_t>((end - start).ToMilliseconds()));
|
static_cast<uint32_t>((end - start).ToMilliseconds()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AccumulateChild(const nsTArray<Accumulation>& aAccumulations)
|
||||||
|
{
|
||||||
|
TelemetryHistogram::AccumulateChild(aAccumulations);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AccumulateChildKeyed(const nsTArray<KeyedAccumulation>& aAccumulations)
|
||||||
|
{
|
||||||
|
TelemetryHistogram::AccumulateChildKeyed(aAccumulations);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ClearHistogram(ID aId)
|
ClearHistogram(ID aId)
|
||||||
{
|
{
|
||||||
|
@ -33,6 +33,9 @@ namespace HangMonitor {
|
|||||||
} // namespace HangMonitor
|
} // namespace HangMonitor
|
||||||
namespace Telemetry {
|
namespace Telemetry {
|
||||||
|
|
||||||
|
struct Accumulation;
|
||||||
|
struct KeyedAccumulation;
|
||||||
|
|
||||||
enum TimerResolution {
|
enum TimerResolution {
|
||||||
Millisecond,
|
Millisecond,
|
||||||
Microsecond
|
Microsecond
|
||||||
@ -125,6 +128,20 @@ void AccumulateCategorical(ID id, const nsCString& label);
|
|||||||
*/
|
*/
|
||||||
void AccumulateTimeDelta(ID id, TimeStamp start, TimeStamp end = TimeStamp::Now());
|
void AccumulateTimeDelta(ID id, TimeStamp start, TimeStamp end = TimeStamp::Now());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accumulate child data into child histograms
|
||||||
|
*
|
||||||
|
* @param aAccumulations - accumulation actions to perform
|
||||||
|
*/
|
||||||
|
void AccumulateChild(const nsTArray<Accumulation>& aAccumulations);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accumulate child data into child keyed histograms
|
||||||
|
*
|
||||||
|
* @param aAccumulations - accumulation actions to perform
|
||||||
|
*/
|
||||||
|
void AccumulateChildKeyed(const nsTArray<KeyedAccumulation>& aAccumulations);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This clears the data for a histogram in TelemetryHistogramEnums.h.
|
* This clears the data for a histogram in TelemetryHistogramEnums.h.
|
||||||
*
|
*
|
||||||
|
84
toolkit/components/telemetry/TelemetryComms.h
Normal file
84
toolkit/components/telemetry/TelemetryComms.h
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
/* -*- 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef Telemetry_Comms_h__
|
||||||
|
#define Telemetry_Comms_h__
|
||||||
|
|
||||||
|
#include "ipc/IPCMessageUtils.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace Telemetry {
|
||||||
|
|
||||||
|
enum ID : uint32_t;
|
||||||
|
|
||||||
|
struct Accumulation
|
||||||
|
{
|
||||||
|
mozilla::Telemetry::ID mId;
|
||||||
|
uint32_t mSample;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct KeyedAccumulation
|
||||||
|
{
|
||||||
|
mozilla::Telemetry::ID mId;
|
||||||
|
uint32_t mSample;
|
||||||
|
nsCString mKey;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Telemetry
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
|
namespace IPC {
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct
|
||||||
|
ParamTraits<mozilla::Telemetry::Accumulation>
|
||||||
|
{
|
||||||
|
typedef mozilla::Telemetry::Accumulation paramType;
|
||||||
|
|
||||||
|
static void Write(Message* aMsg, const paramType& aParam)
|
||||||
|
{
|
||||||
|
aMsg->WriteUInt32(aParam.mId);
|
||||||
|
WriteParam(aMsg, aParam.mSample);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
|
||||||
|
{
|
||||||
|
if (!aMsg->ReadUInt32(aIter, reinterpret_cast<uint32_t*>(&(aResult->mId))) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mSample))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct
|
||||||
|
ParamTraits<mozilla::Telemetry::KeyedAccumulation>
|
||||||
|
{
|
||||||
|
typedef mozilla::Telemetry::KeyedAccumulation paramType;
|
||||||
|
|
||||||
|
static void Write(Message* aMsg, const paramType& aParam)
|
||||||
|
{
|
||||||
|
aMsg->WriteUInt32(aParam.mId);
|
||||||
|
WriteParam(aMsg, aParam.mSample);
|
||||||
|
WriteParam(aMsg, aParam.mKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
|
||||||
|
{
|
||||||
|
if (!aMsg->ReadUInt32(aIter, reinterpret_cast<uint32_t*>(&(aResult->mId))) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mSample)) ||
|
||||||
|
!ReadParam(aMsg, aIter, &(aResult->mKey))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace IPC
|
||||||
|
|
||||||
|
#endif // Telemetry_Comms_h__
|
@ -14,9 +14,12 @@
|
|||||||
#include "nsClassHashtable.h"
|
#include "nsClassHashtable.h"
|
||||||
#include "nsITelemetry.h"
|
#include "nsITelemetry.h"
|
||||||
|
|
||||||
|
#include "mozilla/dom/ContentChild.h"
|
||||||
#include "mozilla/dom/ToJSValue.h"
|
#include "mozilla/dom/ToJSValue.h"
|
||||||
#include "mozilla/StartupTimeline.h"
|
#include "mozilla/StartupTimeline.h"
|
||||||
#include "mozilla/StaticMutex.h"
|
#include "mozilla/StaticMutex.h"
|
||||||
|
#include "mozilla/StaticPtr.h"
|
||||||
|
#include "mozilla/unused.h"
|
||||||
|
|
||||||
#include "TelemetryCommon.h"
|
#include "TelemetryCommon.h"
|
||||||
#include "TelemetryHistogram.h"
|
#include "TelemetryHistogram.h"
|
||||||
@ -31,6 +34,9 @@ using base::FlagHistogram;
|
|||||||
using base::LinearHistogram;
|
using base::LinearHistogram;
|
||||||
using mozilla::StaticMutex;
|
using mozilla::StaticMutex;
|
||||||
using mozilla::StaticMutexAutoLock;
|
using mozilla::StaticMutexAutoLock;
|
||||||
|
using mozilla::StaticAutoPtr;
|
||||||
|
using mozilla::Telemetry::Accumulation;
|
||||||
|
using mozilla::Telemetry::KeyedAccumulation;
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
@ -92,6 +98,7 @@ using mozilla::StaticMutexAutoLock;
|
|||||||
#define EXPIRED_ID "__expired__"
|
#define EXPIRED_ID "__expired__"
|
||||||
#define SUBSESSION_HISTOGRAM_PREFIX "sub#"
|
#define SUBSESSION_HISTOGRAM_PREFIX "sub#"
|
||||||
#define KEYED_HISTOGRAM_NAME_SEPARATOR "#"
|
#define KEYED_HISTOGRAM_NAME_SEPARATOR "#"
|
||||||
|
#define CHILD_HISTOGRAM_SUFFIX "#content"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
@ -185,6 +192,12 @@ AddonMapType gAddonMap;
|
|||||||
// The singleton StatisticsRecorder object for this process.
|
// The singleton StatisticsRecorder object for this process.
|
||||||
base::StatisticsRecorder* gStatisticsRecorder = nullptr;
|
base::StatisticsRecorder* gStatisticsRecorder = nullptr;
|
||||||
|
|
||||||
|
// For batching and sending child process accumulations to the parent
|
||||||
|
nsITimer* gIPCTimer = nullptr;
|
||||||
|
bool gIPCTimerArmed = false;
|
||||||
|
StaticAutoPtr<nsTArray<Accumulation>> gAccumulations;
|
||||||
|
StaticAutoPtr<nsTArray<KeyedAccumulation>> gKeyedAccumulations;
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
@ -204,6 +217,12 @@ const mozilla::Telemetry::ID kRecordingInitiallyDisabledIDs[] = {
|
|||||||
mozilla::Telemetry::TELEMETRY_TEST_KEYED_COUNT_INIT_NO_RECORD
|
mozilla::Telemetry::TELEMETRY_TEST_KEYED_COUNT_INIT_NO_RECORD
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Sending each remote accumulation immediately places undue strain on the
|
||||||
|
// IPC subsystem. Batch the remote accumulations for a period of time before
|
||||||
|
// sending them all at once. This value was chosen as a balance between data
|
||||||
|
// timeliness and performance (see bug 1218576)
|
||||||
|
const uint32_t kBatchTimeoutMs = 2000;
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
@ -412,10 +431,12 @@ internal_GetHistogramEnumId(const char *name, mozilla::Telemetry::ID *id)
|
|||||||
|
|
||||||
// O(1) histogram lookup by numeric id
|
// O(1) histogram lookup by numeric id
|
||||||
nsresult
|
nsresult
|
||||||
internal_GetHistogramByEnumId(mozilla::Telemetry::ID id, Histogram **ret)
|
internal_GetHistogramByEnumId(mozilla::Telemetry::ID id, Histogram **ret,
|
||||||
|
bool child = false)
|
||||||
{
|
{
|
||||||
static Histogram* knownHistograms[mozilla::Telemetry::HistogramCount] = {0};
|
static Histogram* knownHistograms[mozilla::Telemetry::HistogramCount] = {0};
|
||||||
Histogram *h = knownHistograms[id];
|
static Histogram* knownChildHistograms[mozilla::Telemetry::HistogramCount] = {0};
|
||||||
|
Histogram *h = child ? knownChildHistograms[id] : knownHistograms[id];
|
||||||
if (h) {
|
if (h) {
|
||||||
*ret = h;
|
*ret = h;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
@ -426,8 +447,15 @@ internal_GetHistogramByEnumId(mozilla::Telemetry::ID id, Histogram **ret)
|
|||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult rv = internal_HistogramGet(p.id(), p.expiration(), p.histogramType,
|
nsCString histogramName;
|
||||||
p.min, p.max, p.bucketCount, true, &h);
|
histogramName.Append(p.id());
|
||||||
|
if (child) {
|
||||||
|
histogramName.AppendLiteral(CHILD_HISTOGRAM_SUFFIX);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult rv = internal_HistogramGet(histogramName.get(), p.expiration(),
|
||||||
|
p.histogramType, p.min, p.max,
|
||||||
|
p.bucketCount, true, &h);
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
@ -447,7 +475,11 @@ internal_GetHistogramByEnumId(mozilla::Telemetry::ID id, Histogram **ret)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
*ret = knownHistograms[id] = h;
|
if (child) {
|
||||||
|
*ret = knownChildHistograms[id] = h;
|
||||||
|
} else {
|
||||||
|
*ret = knownHistograms[id] = h;
|
||||||
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1681,9 +1713,55 @@ internal_SetHistogramRecordingEnabled(mozilla::Telemetry::ID aID, bool aEnabled)
|
|||||||
MOZ_ASSERT(false, "Telemetry::SetHistogramRecordingEnabled(...) id not found");
|
MOZ_ASSERT(false, "Telemetry::SetHistogramRecordingEnabled(...) id not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void internal_armIPCTimer()
|
||||||
|
{
|
||||||
|
if (gIPCTimerArmed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!gIPCTimer) {
|
||||||
|
CallCreateInstance(NS_TIMER_CONTRACTID, &gIPCTimer);
|
||||||
|
}
|
||||||
|
if (gIPCTimer) {
|
||||||
|
gIPCTimer->InitWithFuncCallback(TelemetryHistogram::IPCTimerFired,
|
||||||
|
nullptr, kBatchTimeoutMs,
|
||||||
|
nsITimer::TYPE_ONE_SHOT);
|
||||||
|
gIPCTimerArmed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
internal_RemoteAccumulate(mozilla::Telemetry::ID aId, uint32_t aSample)
|
||||||
|
{
|
||||||
|
if (XRE_IsParentProcess()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!gAccumulations) {
|
||||||
|
gAccumulations = new nsTArray<Accumulation>();
|
||||||
|
}
|
||||||
|
gAccumulations->AppendElement(Accumulation{aId, aSample});
|
||||||
|
internal_armIPCTimer();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
internal_RemoteAccumulate(mozilla::Telemetry::ID aId,
|
||||||
|
const nsCString& aKey, uint32_t aSample)
|
||||||
|
{
|
||||||
|
if (XRE_IsParentProcess()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!gKeyedAccumulations) {
|
||||||
|
gKeyedAccumulations = new nsTArray<KeyedAccumulation>();
|
||||||
|
}
|
||||||
|
gKeyedAccumulations->AppendElement(KeyedAccumulation{aId, aSample, aKey});
|
||||||
|
internal_armIPCTimer();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void internal_Accumulate(mozilla::Telemetry::ID aHistogram, uint32_t aSample)
|
void internal_Accumulate(mozilla::Telemetry::ID aHistogram, uint32_t aSample)
|
||||||
{
|
{
|
||||||
if (!internal_CanRecordBase()) {
|
if (!internal_CanRecordBase() ||
|
||||||
|
internal_RemoteAccumulate(aHistogram, aSample)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Histogram *h;
|
Histogram *h;
|
||||||
@ -1697,7 +1775,8 @@ void
|
|||||||
internal_Accumulate(mozilla::Telemetry::ID aID,
|
internal_Accumulate(mozilla::Telemetry::ID aID,
|
||||||
const nsCString& aKey, uint32_t aSample)
|
const nsCString& aKey, uint32_t aSample)
|
||||||
{
|
{
|
||||||
if (!gInitDone || !internal_CanRecordBase()) {
|
if (!gInitDone || !internal_CanRecordBase() ||
|
||||||
|
internal_RemoteAccumulate(aID, aKey, aSample)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const HistogramInfo& th = gHistograms[aID];
|
const HistogramInfo& th = gHistograms[aID];
|
||||||
@ -1707,6 +1786,42 @@ internal_Accumulate(mozilla::Telemetry::ID aID,
|
|||||||
keyed->Add(aKey, aSample);
|
keyed->Add(aKey, aSample);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
internal_AccumulateChild(mozilla::Telemetry::ID aId, uint32_t aSample)
|
||||||
|
{
|
||||||
|
if (!internal_CanRecordBase()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Histogram* h;
|
||||||
|
nsresult rv = internal_GetHistogramByEnumId(aId, &h, true);
|
||||||
|
if (NS_SUCCEEDED(rv)) {
|
||||||
|
internal_HistogramAdd(*h, aSample, gHistograms[aId].dataset);
|
||||||
|
} else {
|
||||||
|
NS_WARNING("NS_FAILED GetHistogramByEnumId for CHILD");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
internal_AccumulateChildKeyed(mozilla::Telemetry::ID aId,
|
||||||
|
const nsCString& aKey, uint32_t aSample)
|
||||||
|
{
|
||||||
|
if (!gInitDone || !internal_CanRecordBase()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const HistogramInfo& th = gHistograms[aId];
|
||||||
|
nsCString id;
|
||||||
|
id.Append(th.id());
|
||||||
|
id.AppendLiteral(CHILD_HISTOGRAM_SUFFIX);
|
||||||
|
KeyedHistogram* keyed = internal_GetKeyedHistogramById(id);
|
||||||
|
if (!keyed) {
|
||||||
|
const nsDependentCString expiration(th.expiration());
|
||||||
|
keyed = new KeyedHistogram(id, expiration, th.histogramType, th.min, th.max,
|
||||||
|
th.bucketCount, th.dataset);
|
||||||
|
gKeyedHistograms.Put(id, keyed);
|
||||||
|
}
|
||||||
|
keyed->Add(aKey, aSample);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
@ -1816,6 +1931,11 @@ void TelemetryHistogram::DeInitializeGlobalState()
|
|||||||
gHistogramMap.Clear();
|
gHistogramMap.Clear();
|
||||||
gKeyedHistograms.Clear();
|
gKeyedHistograms.Clear();
|
||||||
gAddonMap.Clear();
|
gAddonMap.Clear();
|
||||||
|
gAccumulations = nullptr;
|
||||||
|
gKeyedAccumulations = nullptr;
|
||||||
|
if (gIPCTimer) {
|
||||||
|
NS_RELEASE(gIPCTimer);
|
||||||
|
}
|
||||||
gInitDone = false;
|
gInitDone = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1921,12 +2041,7 @@ TelemetryHistogram::Accumulate(const char* name, uint32_t sample)
|
|||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
internal_Accumulate(id, sample);
|
||||||
Histogram *h;
|
|
||||||
rv = internal_GetHistogramByEnumId(id, &h);
|
|
||||||
if (NS_SUCCEEDED(rv)) {
|
|
||||||
internal_HistogramAdd(*h, sample, gHistograms[id].dataset);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1952,6 +2067,34 @@ TelemetryHistogram::AccumulateCategorical(mozilla::Telemetry::ID aId,
|
|||||||
internal_HistogramAddCategorical(aId, label);
|
internal_HistogramAddCategorical(aId, label);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TelemetryHistogram::AccumulateChild(const nsTArray<Accumulation>& aAccumulations)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(XRE_IsParentProcess());
|
||||||
|
StaticMutexAutoLock locker(gTelemetryHistogramMutex);
|
||||||
|
if (!internal_CanRecordBase()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (uint32_t i = 0; i < aAccumulations.Length(); ++i) {
|
||||||
|
internal_AccumulateChild(aAccumulations[i].mId, aAccumulations[i].mSample);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TelemetryHistogram::AccumulateChildKeyed(const nsTArray<KeyedAccumulation>& aAccumulations)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(XRE_IsParentProcess());
|
||||||
|
StaticMutexAutoLock locker(gTelemetryHistogramMutex);
|
||||||
|
if (!internal_CanRecordBase()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (uint32_t i = 0; i < aAccumulations.Length(); ++i) {
|
||||||
|
internal_AccumulateChildKeyed(aAccumulations[i].mId,
|
||||||
|
aAccumulations[i].mKey,
|
||||||
|
aAccumulations[i].mSample);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TelemetryHistogram::ClearHistogram(mozilla::Telemetry::ID aId)
|
TelemetryHistogram::ClearHistogram(mozilla::Telemetry::ID aId)
|
||||||
{
|
{
|
||||||
@ -2058,6 +2201,8 @@ TelemetryHistogram::CreateHistogramSnapshots(JSContext *cx,
|
|||||||
mozilla::DebugOnly<nsresult> rv
|
mozilla::DebugOnly<nsresult> rv
|
||||||
= internal_GetHistogramByEnumId(mozilla::Telemetry::ID(i), &h);
|
= internal_GetHistogramByEnumId(mozilla::Telemetry::ID(i), &h);
|
||||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||||
|
rv = internal_GetHistogramByEnumId(mozilla::Telemetry::ID(i), &h, true);
|
||||||
|
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2321,3 +2466,40 @@ TelemetryHistogram::GetHistogramSizesofIncludingThis(mozilla::MallocSizeOf
|
|||||||
}
|
}
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This method takes the lock only to double-buffer the batched telemetry.
|
||||||
|
// It releases the lock before calling out to IPC code which can (and does)
|
||||||
|
// Accumulate (which would deadlock)
|
||||||
|
//
|
||||||
|
// To ensure non-reentrancy, the timer is not released until the method
|
||||||
|
// completes
|
||||||
|
void
|
||||||
|
TelemetryHistogram::IPCTimerFired(nsITimer* aTimer, void* aClosure)
|
||||||
|
{
|
||||||
|
nsTArray<Accumulation> accumulationsToSend;
|
||||||
|
nsTArray<KeyedAccumulation> keyedAccumulationsToSend;
|
||||||
|
{
|
||||||
|
StaticMutexAutoLock locker(gTelemetryHistogramMutex);
|
||||||
|
if (gAccumulations) {
|
||||||
|
accumulationsToSend.SwapElements(*gAccumulations);
|
||||||
|
}
|
||||||
|
if (gKeyedAccumulations) {
|
||||||
|
keyedAccumulationsToSend.SwapElements(*gKeyedAccumulations);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mozilla::dom::ContentChild* contentChild = mozilla::dom::ContentChild::GetSingleton();
|
||||||
|
mozilla::Unused << NS_WARN_IF(!contentChild);
|
||||||
|
if (contentChild) {
|
||||||
|
if (accumulationsToSend.Length()) {
|
||||||
|
mozilla::Unused <<
|
||||||
|
NS_WARN_IF(!contentChild->SendAccumulateChildHistogram(accumulationsToSend));
|
||||||
|
}
|
||||||
|
if (keyedAccumulationsToSend.Length()) {
|
||||||
|
mozilla::Unused <<
|
||||||
|
NS_WARN_IF(!contentChild->SendAccumulateChildKeyedHistogram(keyedAccumulationsToSend));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gIPCTimerArmed = false;
|
||||||
|
}
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
#include "mozilla/TelemetryHistogramEnums.h"
|
#include "mozilla/TelemetryHistogramEnums.h"
|
||||||
|
|
||||||
|
#include "mozilla/TelemetryComms.h"
|
||||||
|
|
||||||
// This module is internal to Telemetry. It encapsulates Telemetry's
|
// This module is internal to Telemetry. It encapsulates Telemetry's
|
||||||
// histogram accumulation and storage logic. It should only be used by
|
// histogram accumulation and storage logic. It should only be used by
|
||||||
// Telemetry.cpp. These functions should not be used anywhere else.
|
// Telemetry.cpp. These functions should not be used anywhere else.
|
||||||
@ -42,6 +44,9 @@ void Accumulate(const char* name, const nsCString& key, uint32_t sample);
|
|||||||
|
|
||||||
void AccumulateCategorical(mozilla::Telemetry::ID aId, const nsCString& aLabel);
|
void AccumulateCategorical(mozilla::Telemetry::ID aId, const nsCString& aLabel);
|
||||||
|
|
||||||
|
void AccumulateChild(const nsTArray<mozilla::Telemetry::Accumulation>& aAccumulations);
|
||||||
|
void AccumulateChildKeyed(const nsTArray<mozilla::Telemetry::KeyedAccumulation>& aAccumulations);
|
||||||
|
|
||||||
void
|
void
|
||||||
ClearHistogram(mozilla::Telemetry::ID aId);
|
ClearHistogram(mozilla::Telemetry::ID aId);
|
||||||
|
|
||||||
@ -96,6 +101,8 @@ GetMapShallowSizesOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf);
|
|||||||
size_t
|
size_t
|
||||||
GetHistogramSizesofIncludingThis(mozilla::MallocSizeOf aMallocSizeOf);
|
GetHistogramSizesofIncludingThis(mozilla::MallocSizeOf aMallocSizeOf);
|
||||||
|
|
||||||
|
void
|
||||||
|
IPCTimerFired(nsITimer* aTimer, void* aClosure);
|
||||||
} // namespace TelemetryHistogram
|
} // namespace TelemetryHistogram
|
||||||
|
|
||||||
#endif // TelemetryHistogram_h__
|
#endif // TelemetryHistogram_h__
|
||||||
|
@ -19,6 +19,7 @@ EXPORTS.mozilla += [
|
|||||||
'!TelemetryScalarEnums.h',
|
'!TelemetryScalarEnums.h',
|
||||||
'ProcessedStack.h',
|
'ProcessedStack.h',
|
||||||
'Telemetry.h',
|
'Telemetry.h',
|
||||||
|
'TelemetryComms.h',
|
||||||
'ThreadHangStats.h',
|
'ThreadHangStats.h',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user