mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-06 00:10:25 +00:00
Bug 1181175 - Telemetry for finding out how often our process is rescheduled to another CPU. r=jandem, r=bsmedberg
--HG-- extra : transplant_source : %94Od-%F4U%88U%0C%DA%28%F3%B6%8D%7F%E7%88%1FTH
This commit is contained in:
parent
d326242e8b
commit
4daefcd581
@ -5680,6 +5680,11 @@ GetStopwatchIsMonitoringPerCompartment(JSRuntime*);
|
||||
extern JS_PUBLIC_API(bool)
|
||||
IsStopwatchActive(JSRuntime*);
|
||||
|
||||
// Extract the CPU rescheduling data.
|
||||
extern JS_PUBLIC_API(void)
|
||||
GetPerfMonitoringTestCpuRescheduling(JSRuntime*, uint64_t* stayed, uint64_t* moved);
|
||||
|
||||
|
||||
/**
|
||||
* Add a number of microseconds to the time spent waiting on CPOWs
|
||||
* since process start.
|
||||
|
@ -57,8 +57,8 @@
|
||||
#include "vm/Stack-inl.h"
|
||||
|
||||
#if defined(XP_WIN)
|
||||
#include <Windows.h>
|
||||
#include <Processthreadsapi.h>
|
||||
#include <processthreadsapi.h>
|
||||
#include <windows.h>
|
||||
#endif // defined(XP_WIN)
|
||||
|
||||
using namespace js;
|
||||
@ -396,7 +396,7 @@ class AutoStopwatch final
|
||||
|
||||
// The CPU on which we started the measure. Defined only
|
||||
// if `isMonitoringJank_` is `true`.
|
||||
#if defined(XP_WIN) && _WIN32_WINNT >= 0x0601
|
||||
#if defined(XP_WIN) && WINVER >= _WIN32_WINNT_VISTA
|
||||
struct cpuid_t {
|
||||
WORD group_;
|
||||
BYTE number_;
|
||||
@ -531,6 +531,12 @@ class AutoStopwatch final
|
||||
const uint64_t cyclesEnd = getCycles();
|
||||
cyclesDelta = getDelta(cyclesEnd, cyclesStart_);
|
||||
}
|
||||
#if (defined(XP_WIN) && WINVER >= _WIN32_WINNT_VISTA) || defined(XP_LINUX)
|
||||
if (isSameCPU(cpuStart_, cpuEnd))
|
||||
runtime->stopwatch.testCpuRescheduling.stayed += 1;
|
||||
else
|
||||
runtime->stopwatch.testCpuRescheduling.moved += 1;
|
||||
#endif // defined(XP_WIN) || defined(XP_LINUX)
|
||||
}
|
||||
|
||||
uint64_t CPOWTimeDelta = 0;
|
||||
@ -621,7 +627,7 @@ class AutoStopwatch final
|
||||
// access to the current CPU.
|
||||
cpuid_t inline getCPU() const
|
||||
{
|
||||
#if defined(XP_WIN)
|
||||
#if defined(XP_WIN) && WINVER >= _WIN32_WINNT_VISTA
|
||||
PROCESSOR_NUMBER proc;
|
||||
GetCurrentProcessorNumberEx(&proc);
|
||||
|
||||
@ -637,7 +643,7 @@ class AutoStopwatch final
|
||||
// Compare two CPU identifiers.
|
||||
bool inline isSameCPU(const cpuid_t& a, const cpuid_t& b) const
|
||||
{
|
||||
#if defined(XP_WIN)
|
||||
#if defined(XP_WIN) && WINVER >= _WIN32_WINNT_VISTA
|
||||
return a.group_ == b.group_ && a.number_ == b.number_;
|
||||
#elif defined(XP_LINUX)
|
||||
return a == b;
|
||||
|
@ -1208,6 +1208,13 @@ js::GetStopwatchIsMonitoringPerCompartment(JSRuntime* rt)
|
||||
return rt->stopwatch.isMonitoringPerCompartment();
|
||||
}
|
||||
|
||||
void
|
||||
js::GetPerfMonitoringTestCpuRescheduling(JSRuntime* rt, uint64_t* stayed, uint64_t* moved)
|
||||
{
|
||||
*stayed = rt->stopwatch.testCpuRescheduling.stayed;
|
||||
*moved = rt->stopwatch.testCpuRescheduling.moved;
|
||||
}
|
||||
|
||||
js::PerformanceGroupHolder::~PerformanceGroupHolder()
|
||||
{
|
||||
unlink();
|
||||
|
@ -1680,6 +1680,33 @@ struct JSRuntime : public JS::shadow::Runtime,
|
||||
// The total amount of time spent waiting on CPOWs since the
|
||||
// start of the process, in microseconds.
|
||||
uint64_t totalCPOWTime;
|
||||
|
||||
// Data extracted by the AutoStopwatch to determine how often
|
||||
// we reschedule the process to a different CPU during the
|
||||
// execution of JS.
|
||||
//
|
||||
// Warning: These values are incremented *only* on platforms
|
||||
// that offer a syscall/libcall to check on which CPU a
|
||||
// process is currently executed.
|
||||
struct TestCpuRescheduling
|
||||
{
|
||||
// Incremented once we have finished executing code
|
||||
// in a group, if the CPU on which we started
|
||||
// execution is the same as the CPU on which
|
||||
// we finished.
|
||||
uint64_t stayed;
|
||||
// Incremented once we have finished executing code
|
||||
// in a group, if the CPU on which we started
|
||||
// execution is different from the CPU on which
|
||||
// we finished.
|
||||
uint64_t moved;
|
||||
TestCpuRescheduling()
|
||||
: stayed(0),
|
||||
moved(0)
|
||||
{ }
|
||||
};
|
||||
TestCpuRescheduling testCpuRescheduling;
|
||||
|
||||
private:
|
||||
Stopwatch(const Stopwatch&) = delete;
|
||||
Stopwatch& operator=(const Stopwatch&) = delete;
|
||||
|
@ -21,6 +21,10 @@
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsGlobalWindow.h"
|
||||
|
||||
#include "mozilla/unused.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
|
||||
#if defined(XP_WIN)
|
||||
#include "windows.h"
|
||||
#else
|
||||
@ -440,7 +444,7 @@ NS_IMETHODIMP nsPerformanceSnapshot::GetProcessData(nsIPerformanceStats * *aProc
|
||||
}
|
||||
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsPerformanceStatsService, nsIPerformanceStatsService)
|
||||
NS_IMPL_ISUPPORTS(nsPerformanceStatsService, nsIPerformanceStatsService, nsIObserver)
|
||||
|
||||
nsPerformanceStatsService::nsPerformanceStatsService()
|
||||
#if defined(XP_WIN)
|
||||
@ -448,7 +452,13 @@ nsPerformanceStatsService::nsPerformanceStatsService()
|
||||
#else
|
||||
: mProcessId(getpid())
|
||||
#endif
|
||||
, mProcessStayed(0)
|
||||
, mProcessMoved(0)
|
||||
{
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
if (obs) {
|
||||
mozilla::unused << obs->AddObserver(this, "profile-before-shutdown", false);
|
||||
}
|
||||
}
|
||||
|
||||
nsPerformanceStatsService::~nsPerformanceStatsService()
|
||||
@ -507,8 +517,28 @@ NS_IMETHODIMP nsPerformanceStatsService::GetSnapshot(JSContext* cx, nsIPerforman
|
||||
return rv;
|
||||
}
|
||||
|
||||
js::GetPerfMonitoringTestCpuRescheduling(JS_GetRuntime(cx), &mProcessStayed, &mProcessMoved);
|
||||
snapshot.forget(aSnapshot);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
/* void observe (in nsISupports aSubject, in string aTopic, in wstring aData); */
|
||||
NS_IMETHODIMP nsPerformanceStatsService::Observe(nsISupports *, const char *, const char16_t *)
|
||||
{
|
||||
// Upload telemetry
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
if (obs) {
|
||||
mozilla::unused << obs->RemoveObserver(this, "profile-before-shutdown");
|
||||
}
|
||||
|
||||
if (mProcessStayed + mProcessMoved == 0) {
|
||||
// Nothing to report.
|
||||
return NS_OK;
|
||||
}
|
||||
const uint32_t proportion = ( 100 * mProcessStayed ) / ( mProcessStayed + mProcessMoved );
|
||||
mozilla::Telemetry::Accumulate("PERF_MONITORING_TEST_CPU_RESCHEDULING_PROPORTION_MOVED", proportion);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -6,13 +6,16 @@
|
||||
#ifndef nsPerformanceStats_h
|
||||
#define nsPerformanceStats_h
|
||||
|
||||
#include "nsIObserver.h"
|
||||
|
||||
#include "nsIPerformanceStats.h"
|
||||
|
||||
class nsPerformanceStatsService : public nsIPerformanceStatsService
|
||||
class nsPerformanceStatsService : public nsIPerformanceStatsService, nsIObserver
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIPERFORMANCESTATSSERVICE
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
nsPerformanceStatsService();
|
||||
|
||||
@ -20,6 +23,8 @@ private:
|
||||
virtual ~nsPerformanceStatsService();
|
||||
|
||||
const uint64_t mProcessId;
|
||||
uint64_t mProcessStayed;
|
||||
uint64_t mProcessMoved;
|
||||
protected:
|
||||
};
|
||||
|
||||
|
@ -8671,5 +8671,13 @@
|
||||
"expires_in_version": "44",
|
||||
"kind": "boolean",
|
||||
"description": "Was there an error while performing the v7 permissions DB migration?"
|
||||
},
|
||||
"PERF_MONITORING_TEST_CPU_RESCHEDULING_PROPORTION_MOVED": {
|
||||
"alert_emails": ["dteller@mozilla.com"],
|
||||
"expires_in_version": "44",
|
||||
"kind": "linear",
|
||||
"high": "100",
|
||||
"n_buckets": "20",
|
||||
"description": "Proportion (%) of reschedulings of the main process to another CPU during the execution of code inside a JS compartment. Updated while we are measuring jank."
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user