bug 679427 - make event loop responsiveness threshold and interval configurable via environment variable. r=jlebar

This commit is contained in:
Ted Mielczarek 2011-09-09 08:51:08 -04:00
parent b3dc798c06
commit 8cb2a8ef38

View File

@ -52,6 +52,18 @@
* Set MOZ_INSTRUMENT_EVENT_LOOP_OUTPUT in the environment to a
* file path to contain the log output, the default is to log to stdout.
*
* Set MOZ_INSTRUMENT_EVENT_LOOP_THRESHOLD in the environment to an
* integer number of milliseconds to change the threshold for reporting.
* The default is 20 milliseconds. Unresponsive periods shorter than this
* threshold will not be reported.
*
* Set MOZ_INSTRUMENT_EVENT_LOOP_INTERVAL in the environment to an
* integer number of milliseconds to change the maximum sampling frequency.
* This variable controls how often events will be sent to the main
* thread's event loop to sample responsiveness. The sampler will not
* send events twice within LOOP_INTERVAL milliseconds.
* The default is 10 milliseconds.
*
* All logged output lines start with MOZ_EVENT_TRACE. All timestamps
* output are milliseconds since the epoch (PRTime / 1000).
*
@ -75,6 +87,7 @@
#include "mozilla/TimeStamp.h"
#include "mozilla/WidgetTraceEvent.h"
#include <limits.h>
#include <prenv.h>
#include <prinrval.h>
#include <prthread.h>
@ -101,9 +114,12 @@ bool sExit = false;
*/
void TracerThread(void *arg)
{
// These are the defaults. They can be overridden by environment vars.
// This should be set to the maximum latency we'd like to allow
// for responsiveness.
const PRIntervalTime kMeasureInterval = PR_MillisecondsToInterval(50);
PRIntervalTime threshold = PR_MillisecondsToInterval(20);
// This is the sampling interval.
PRIntervalTime interval = PR_MillisecondsToInterval(10);
FILE* log = NULL;
char* envfile = PR_GetEnv("MOZ_INSTRUMENT_EVENT_LOOP_OUTPUT");
@ -113,19 +129,35 @@ void TracerThread(void *arg)
if (log == NULL)
log = stdout;
char* thresholdenv = PR_GetEnv("MOZ_INSTRUMENT_EVENT_LOOP_THRESHOLD");
if (thresholdenv && *thresholdenv) {
int val = atoi(thresholdenv);
if (val != 0 && val != INT_MAX && val != INT_MIN) {
threshold = PR_MillisecondsToInterval(val);
}
}
char* intervalenv = PR_GetEnv("MOZ_INSTRUMENT_EVENT_LOOP_INTERVAL");
if (intervalenv && *intervalenv) {
int val = atoi(intervalenv);
if (val != 0 && val != INT_MAX && val != INT_MIN) {
interval = PR_MillisecondsToInterval(val);
}
}
fprintf(log, "MOZ_EVENT_TRACE start %llu\n", PR_Now() / PR_USEC_PER_MSEC);
while (!sExit) {
TimeStamp start(TimeStamp::Now());
PRIntervalTime next_sleep = kMeasureInterval;
PRIntervalTime next_sleep = interval;
//TODO: only wait up to a maximum of kMeasureInterval, return
//TODO: only wait up to a maximum of interval; return
// early if that threshold is exceeded and dump a stack trace
// or do something else useful.
if (FireAndWaitForTracerEvent()) {
TimeDuration duration = TimeStamp::Now() - start;
// Only report samples that exceed our measurement interval.
if (duration.ToMilliseconds() > kMeasureInterval) {
// Only report samples that exceed our measurement threshold.
if (duration.ToMilliseconds() > threshold) {
fprintf(log, "MOZ_EVENT_TRACE sample %llu %d\n",
PR_Now() / PR_USEC_PER_MSEC,
int(duration.ToSecondsSigDigits() * 1000));