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:
David Rajchenbach-Teller 2015-07-29 19:01:05 +02:00
parent d326242e8b
commit 4daefcd581
7 changed files with 95 additions and 7 deletions

View File

@ -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.

View File

@ -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;

View File

@ -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();

View File

@ -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;

View File

@ -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;
}

View File

@ -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:
};

View File

@ -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."
}
}