зеркало из https://github.com/mozilla/gecko-dev.git
Bug 815709 - Shutdown time is read in the main thread. r=ehsan.
Move code to Telemetry.cpp and s/NULL/nullptr/.
This commit is contained in:
Родитель
e96ed28ecd
Коммит
b2ccc613ee
|
@ -40,6 +40,7 @@ NS_VISIBILITY_DEFAULT __attribute__((weak));
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
void RecordShutdownEndTimeStamp();
|
void RecordShutdownEndTimeStamp();
|
||||||
|
void RecordShutdownStartTimeStamp();
|
||||||
|
|
||||||
class StartupTimeline {
|
class StartupTimeline {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -163,9 +163,7 @@ nsAppStartup::nsAppStartup() :
|
||||||
mRestart(false),
|
mRestart(false),
|
||||||
mInterrupted(false),
|
mInterrupted(false),
|
||||||
mIsSafeModeNecessary(false),
|
mIsSafeModeNecessary(false),
|
||||||
mStartupCrashTrackingEnded(false),
|
mStartupCrashTrackingEnded(false)
|
||||||
mCachedShutdownTime(false),
|
|
||||||
mLastShutdownTime(0)
|
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
|
||||||
|
@ -296,83 +294,7 @@ nsAppStartup::Run(void)
|
||||||
return mRestart ? NS_SUCCESS_RESTART_APP : NS_OK;
|
return mRestart ? NS_SUCCESS_RESTART_APP : NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static TimeStamp gRecordedShutdownStartTime;
|
|
||||||
static bool gAlreadyFreedShutdownTimeFileName = false;
|
|
||||||
static char *gRecordedShutdownTimeFileName = NULL;
|
|
||||||
|
|
||||||
static char *
|
|
||||||
GetShutdownTimeFileName()
|
|
||||||
{
|
|
||||||
if (gAlreadyFreedShutdownTimeFileName) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!gRecordedShutdownTimeFileName) {
|
|
||||||
nsCOMPtr<nsIFile> mozFile;
|
|
||||||
NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(mozFile));
|
|
||||||
if (!mozFile)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
mozFile->AppendNative(NS_LITERAL_CSTRING("Telemetry.ShutdownTime.txt"));
|
|
||||||
nsAutoCString nativePath;
|
|
||||||
nsresult rv = mozFile->GetNativePath(nativePath);
|
|
||||||
if (!NS_SUCCEEDED(rv))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
gRecordedShutdownTimeFileName = PL_strdup(nativePath.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
return gRecordedShutdownTimeFileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
RecordShutdownStartTimeStamp() {
|
|
||||||
if (!Telemetry::CanRecord())
|
|
||||||
return;
|
|
||||||
|
|
||||||
gRecordedShutdownStartTime = TimeStamp::Now();
|
|
||||||
|
|
||||||
GetShutdownTimeFileName();
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace mozilla {
|
|
||||||
void
|
|
||||||
RecordShutdownEndTimeStamp() {
|
|
||||||
if (!gRecordedShutdownTimeFileName || gAlreadyFreedShutdownTimeFileName)
|
|
||||||
return;
|
|
||||||
|
|
||||||
nsCString name(gRecordedShutdownTimeFileName);
|
|
||||||
PL_strfree(gRecordedShutdownTimeFileName);
|
|
||||||
gRecordedShutdownTimeFileName = NULL;
|
|
||||||
gAlreadyFreedShutdownTimeFileName = true;
|
|
||||||
|
|
||||||
nsCString tmpName = name;
|
|
||||||
tmpName += ".tmp";
|
|
||||||
FILE *f = fopen(tmpName.get(), "w");
|
|
||||||
if (!f)
|
|
||||||
return;
|
|
||||||
// On a normal release build this should be called just before
|
|
||||||
// calling _exit, but on a debug build or when the user forces a full
|
|
||||||
// shutdown this is called as late as possible, so we have to
|
|
||||||
// white list this write as write poisoning will be enabled.
|
|
||||||
int fd = fileno(f);
|
|
||||||
MozillaRegisterDebugFD(fd);
|
|
||||||
|
|
||||||
TimeStamp now = TimeStamp::Now();
|
|
||||||
MOZ_ASSERT(now >= gRecordedShutdownStartTime);
|
|
||||||
TimeDuration diff = now - gRecordedShutdownStartTime;
|
|
||||||
uint32_t diff2 = diff.ToMilliseconds();
|
|
||||||
int written = fprintf(f, "%d\n", diff2);
|
|
||||||
MozillaUnRegisterDebugFILE(f);
|
|
||||||
int rv = fclose(f);
|
|
||||||
if (written < 0 || rv != 0) {
|
|
||||||
PR_Delete(tmpName.get());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
PR_Delete(name.get());
|
|
||||||
PR_Rename(tmpName.get(), name.get());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsAppStartup::Quit(uint32_t aMode)
|
nsAppStartup::Quit(uint32_t aMode)
|
||||||
|
@ -389,7 +311,7 @@ nsAppStartup::Quit(uint32_t aMode)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
||||||
SAMPLE_MARKER("Shutdown start");
|
SAMPLE_MARKER("Shutdown start");
|
||||||
RecordShutdownStartTimeStamp();
|
mozilla::RecordShutdownStartTimeStamp();
|
||||||
|
|
||||||
// If we're considering quitting, we will only do so if:
|
// If we're considering quitting, we will only do so if:
|
||||||
if (ferocity == eConsiderQuit) {
|
if (ferocity == eConsiderQuit) {
|
||||||
|
@ -588,47 +510,6 @@ nsAppStartup::ExitLastWindowClosingSurvivalArea(void)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsAppStartup::GetLastShutdownDuration(uint32_t *aResult)
|
|
||||||
{
|
|
||||||
// We make this check so that GetShutdownTimeFileName() doesn't get
|
|
||||||
// called; calling that function without telemetry enabled violates
|
|
||||||
// assumptions that the write-the-shutdown-timestamp machinery makes.
|
|
||||||
if (!Telemetry::CanRecord()) {
|
|
||||||
*aResult = 0;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mCachedShutdownTime) {
|
|
||||||
const char *filename = GetShutdownTimeFileName();
|
|
||||||
|
|
||||||
if (!filename) {
|
|
||||||
*aResult = 0;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
FILE *f = fopen(filename, "r");
|
|
||||||
if (!f) {
|
|
||||||
*aResult = 0;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int shutdownTime;
|
|
||||||
int r = fscanf(f, "%d\n", &shutdownTime);
|
|
||||||
fclose(f);
|
|
||||||
if (r != 1) {
|
|
||||||
*aResult = 0;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
mLastShutdownTime = shutdownTime;
|
|
||||||
mCachedShutdownTime = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
*aResult = mLastShutdownTime;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// nsAppStartup->nsIAppStartup2
|
// nsAppStartup->nsIAppStartup2
|
||||||
//
|
//
|
||||||
|
|
|
@ -61,8 +61,6 @@ private:
|
||||||
bool mInterrupted; // Was startup interrupted by an interactive prompt?
|
bool mInterrupted; // Was startup interrupted by an interactive prompt?
|
||||||
bool mIsSafeModeNecessary; // Whether safe mode is necessary
|
bool mIsSafeModeNecessary; // Whether safe mode is necessary
|
||||||
bool mStartupCrashTrackingEnded; // Whether startup crash tracking has already ended
|
bool mStartupCrashTrackingEnded; // Whether startup crash tracking has already ended
|
||||||
bool mCachedShutdownTime;
|
|
||||||
uint32_t mLastShutdownTime;
|
|
||||||
|
|
||||||
#if defined(XP_WIN)
|
#if defined(XP_WIN)
|
||||||
//Interaction with OS-provided profiling probes
|
//Interaction with OS-provided profiling probes
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
interface nsICmdLineService;
|
interface nsICmdLineService;
|
||||||
|
|
||||||
[scriptable, uuid(5016bc45-54d9-4f97-935c-df4cef4b999f)]
|
[scriptable, uuid(2b51b67f-6f05-4145-b37e-7369bbc92b19)]
|
||||||
interface nsIAppStartup : nsISupports
|
interface nsIAppStartup : nsISupports
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
@ -42,12 +42,6 @@ interface nsIAppStartup : nsISupports
|
||||||
void enterLastWindowClosingSurvivalArea();
|
void enterLastWindowClosingSurvivalArea();
|
||||||
void exitLastWindowClosingSurvivalArea();
|
void exitLastWindowClosingSurvivalArea();
|
||||||
|
|
||||||
/**
|
|
||||||
* The amount of time, in milliseconds, that the last session took
|
|
||||||
* to shutdown. Reads as 0 to indicate failure.
|
|
||||||
*/
|
|
||||||
readonly attribute uint32_t lastShutdownDuration;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Startup Crash Detection
|
* Startup Crash Detection
|
||||||
*
|
*
|
||||||
|
|
|
@ -24,12 +24,15 @@
|
||||||
#include "nsBaseHashtable.h"
|
#include "nsBaseHashtable.h"
|
||||||
#include "nsXULAppAPI.h"
|
#include "nsXULAppAPI.h"
|
||||||
#include "nsThreadUtils.h"
|
#include "nsThreadUtils.h"
|
||||||
|
#include "plstr.h"
|
||||||
|
#include "nsAppDirectoryServiceDefs.h"
|
||||||
#include "mozilla/ProcessedStack.h"
|
#include "mozilla/ProcessedStack.h"
|
||||||
#include "mozilla/Mutex.h"
|
#include "mozilla/Mutex.h"
|
||||||
#include "mozilla/FileUtils.h"
|
#include "mozilla/FileUtils.h"
|
||||||
#include "mozilla/Preferences.h"
|
#include "mozilla/Preferences.h"
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
#include "mozilla/Likely.h"
|
#include "mozilla/Likely.h"
|
||||||
|
#include "mozilla/mozPoisonWrite.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -313,6 +316,9 @@ private:
|
||||||
HangReports mHangReports;
|
HangReports mHangReports;
|
||||||
Mutex mHangReportsMutex;
|
Mutex mHangReportsMutex;
|
||||||
nsIMemoryReporter *mMemoryReporter;
|
nsIMemoryReporter *mMemoryReporter;
|
||||||
|
|
||||||
|
bool mCachedShutdownTime;
|
||||||
|
uint32_t mLastShutdownTime;
|
||||||
};
|
};
|
||||||
|
|
||||||
TelemetryImpl* TelemetryImpl::sTelemetry = NULL;
|
TelemetryImpl* TelemetryImpl::sTelemetry = NULL;
|
||||||
|
@ -680,11 +686,83 @@ WrapAndReturnHistogram(Histogram *h, JSContext *cx, jsval *ret)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static TimeStamp gRecordedShutdownStartTime;
|
||||||
|
static bool gAlreadyFreedShutdownTimeFileName = false;
|
||||||
|
static char *gRecordedShutdownTimeFileName = nullptr;
|
||||||
|
|
||||||
|
static char *
|
||||||
|
GetShutdownTimeFileName()
|
||||||
|
{
|
||||||
|
if (gAlreadyFreedShutdownTimeFileName) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gRecordedShutdownTimeFileName) {
|
||||||
|
nsCOMPtr<nsIFile> mozFile;
|
||||||
|
NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(mozFile));
|
||||||
|
if (!mozFile)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
mozFile->AppendNative(NS_LITERAL_CSTRING("Telemetry.ShutdownTime.txt"));
|
||||||
|
nsAutoCString nativePath;
|
||||||
|
nsresult rv = mozFile->GetNativePath(nativePath);
|
||||||
|
if (!NS_SUCCEEDED(rv))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
gRecordedShutdownTimeFileName = PL_strdup(nativePath.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
return gRecordedShutdownTimeFileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
TelemetryImpl::GetLastShutdownDuration(uint32_t *aResult)
|
||||||
|
{
|
||||||
|
// We make this check so that GetShutdownTimeFileName() doesn't get
|
||||||
|
// called; calling that function without telemetry enabled violates
|
||||||
|
// assumptions that the write-the-shutdown-timestamp machinery makes.
|
||||||
|
if (!Telemetry::CanRecord()) {
|
||||||
|
*aResult = 0;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mCachedShutdownTime) {
|
||||||
|
const char *filename = GetShutdownTimeFileName();
|
||||||
|
|
||||||
|
if (!filename) {
|
||||||
|
*aResult = 0;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *f = fopen(filename, "r");
|
||||||
|
if (!f) {
|
||||||
|
*aResult = 0;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int shutdownTime;
|
||||||
|
int r = fscanf(f, "%d\n", &shutdownTime);
|
||||||
|
fclose(f);
|
||||||
|
if (r != 1) {
|
||||||
|
*aResult = 0;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
mLastShutdownTime = shutdownTime;
|
||||||
|
mCachedShutdownTime = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
*aResult = mLastShutdownTime;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
TelemetryImpl::TelemetryImpl():
|
TelemetryImpl::TelemetryImpl():
|
||||||
mHistogramMap(Telemetry::HistogramCount),
|
mHistogramMap(Telemetry::HistogramCount),
|
||||||
mCanRecord(XRE_GetProcessType() == GeckoProcessType_Default),
|
mCanRecord(XRE_GetProcessType() == GeckoProcessType_Default),
|
||||||
mHashMutex("Telemetry::mHashMutex"),
|
mHashMutex("Telemetry::mHashMutex"),
|
||||||
mHangReportsMutex("Telemetry::mHangReportsMutex")
|
mHangReportsMutex("Telemetry::mHangReportsMutex"),
|
||||||
|
mCachedShutdownTime(false),
|
||||||
|
mLastShutdownTime(0)
|
||||||
{
|
{
|
||||||
// A whitelist to prevent Telemetry reporting on Addon & Thunderbird DBs
|
// A whitelist to prevent Telemetry reporting on Addon & Thunderbird DBs
|
||||||
const char *trackedDBs[] = {
|
const char *trackedDBs[] = {
|
||||||
|
@ -1673,6 +1751,53 @@ const Module kTelemetryModule = {
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
void
|
||||||
|
RecordShutdownStartTimeStamp() {
|
||||||
|
if (!Telemetry::CanRecord())
|
||||||
|
return;
|
||||||
|
|
||||||
|
gRecordedShutdownStartTime = TimeStamp::Now();
|
||||||
|
|
||||||
|
GetShutdownTimeFileName();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RecordShutdownEndTimeStamp() {
|
||||||
|
if (!gRecordedShutdownTimeFileName || gAlreadyFreedShutdownTimeFileName)
|
||||||
|
return;
|
||||||
|
|
||||||
|
nsCString name(gRecordedShutdownTimeFileName);
|
||||||
|
PL_strfree(gRecordedShutdownTimeFileName);
|
||||||
|
gRecordedShutdownTimeFileName = nullptr;
|
||||||
|
gAlreadyFreedShutdownTimeFileName = true;
|
||||||
|
|
||||||
|
nsCString tmpName = name;
|
||||||
|
tmpName += ".tmp";
|
||||||
|
FILE *f = fopen(tmpName.get(), "w");
|
||||||
|
if (!f)
|
||||||
|
return;
|
||||||
|
// On a normal release build this should be called just before
|
||||||
|
// calling _exit, but on a debug build or when the user forces a full
|
||||||
|
// shutdown this is called as late as possible, so we have to
|
||||||
|
// white list this write as write poisoning will be enabled.
|
||||||
|
int fd = fileno(f);
|
||||||
|
MozillaRegisterDebugFD(fd);
|
||||||
|
|
||||||
|
TimeStamp now = TimeStamp::Now();
|
||||||
|
MOZ_ASSERT(now >= gRecordedShutdownStartTime);
|
||||||
|
TimeDuration diff = now - gRecordedShutdownStartTime;
|
||||||
|
uint32_t diff2 = diff.ToMilliseconds();
|
||||||
|
int written = fprintf(f, "%d\n", diff2);
|
||||||
|
MozillaUnRegisterDebugFILE(f);
|
||||||
|
int rv = fclose(f);
|
||||||
|
if (written < 0 || rv != 0) {
|
||||||
|
PR_Delete(tmpName.get());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
PR_Delete(name.get());
|
||||||
|
PR_Rename(tmpName.get(), name.get());
|
||||||
|
}
|
||||||
|
|
||||||
namespace Telemetry {
|
namespace Telemetry {
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -147,7 +147,7 @@ function getSimpleMeasurements() {
|
||||||
.getService(Ci.nsIJSEngineTelemetryStats)
|
.getService(Ci.nsIJSEngineTelemetryStats)
|
||||||
.telemetryValue;
|
.telemetryValue;
|
||||||
|
|
||||||
let shutdownDuration = Services.startup.lastShutdownDuration;
|
let shutdownDuration = Telemetry.lastShutdownDuration;
|
||||||
if (shutdownDuration)
|
if (shutdownDuration)
|
||||||
ret.shutdownDuration = shutdownDuration;
|
ret.shutdownDuration = shutdownDuration;
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#include "nsISupports.idl"
|
#include "nsISupports.idl"
|
||||||
#include "nsIFile.idl"
|
#include "nsIFile.idl"
|
||||||
|
|
||||||
[scriptable, uuid(de54f594-4c20-4968-a27a-83b38ff952b9)]
|
[scriptable, uuid(420ebbd5-efe3-42f2-8a13-f695e0fdcca0)]
|
||||||
interface nsITelemetry : nsISupports
|
interface nsITelemetry : nsISupports
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
@ -36,6 +36,12 @@ interface nsITelemetry : nsISupports
|
||||||
[implicit_jscontext]
|
[implicit_jscontext]
|
||||||
readonly attribute jsval histogramSnapshots;
|
readonly attribute jsval histogramSnapshots;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The amount of time, in milliseconds, that the last session took
|
||||||
|
* to shutdown. Reads as 0 to indicate failure.
|
||||||
|
*/
|
||||||
|
readonly attribute uint32_t lastShutdownDuration;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* An object containing information about slow SQL statements.
|
* An object containing information about slow SQL statements.
|
||||||
*
|
*
|
||||||
|
|
Загрузка…
Ссылка в новой задаче