Bug 852250 - When restarting recompute the process startup timestamp instead of using the timestamp stored it in MOZ_APP_RESTART during the shutdown procedure. r=nfroyd

This commit is contained in:
Gabriele Svelto 2013-07-31 12:51:58 +02:00
parent 55022997b9
commit e27e54667f
6 changed files with 93 additions and 143 deletions

64
xpcom/ds/TimeStamp.cpp Normal file
View File

@ -0,0 +1,64 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* Implementation of the OS-independent methods of the TimeStamp class
*/
#include "mozilla/TimeStamp.h"
#include "prenv.h"
namespace mozilla {
TimeStamp TimeStamp::sFirstTimeStamp;
TimeStamp TimeStamp::sProcessCreation;
TimeStamp
TimeStamp::ProcessCreation(bool& aIsInconsistent)
{
aIsInconsistent = false;
if (sProcessCreation.IsNull()) {
char *mozAppRestart = PR_GetEnv("MOZ_APP_RESTART");
TimeStamp ts;
/* When calling PR_SetEnv() with an empty value the existing variable may
* be unset or set to the empty string depending on the underlying platform
* thus we have to check if the variable is present and not empty. */
if (mozAppRestart && (strcmp(mozAppRestart, "") != 0)) {
/* Firefox was restarted, use the first time-stamp we've taken as the new
* process startup time and unset MOZ_APP_RESTART. */
ts = sFirstTimeStamp;
PR_SetEnv("MOZ_APP_RESTART=");
} else {
TimeStamp now = Now();
uint64_t uptime = ComputeProcessUptime();
ts = now - TimeDuration::FromMicroseconds(uptime);
if ((ts > sFirstTimeStamp) || (uptime == 0)) {
/* If the process creation timestamp was inconsistent replace it with
* the first one instead and notify that a telemetry error was
* detected. */
aIsInconsistent = true;
ts = sFirstTimeStamp;
}
}
sProcessCreation = ts;
}
return sProcessCreation;
}
void
TimeStamp::RecordProcessRestart()
{
PR_SetEnv("MOZ_APP_RESTART=1");
sProcessCreation = TimeStamp();
}
} // namespace mozilla

View File

@ -342,6 +342,16 @@ private:
static TimeStamp Now(bool aHighResolution);
/**
* Computes the uptime of the current process in microseconds. The result
* is platform-dependent and needs to be checked against existing timestamps
* for consistency.
*
* @returns The number of microseconds since the calling process was started
* or 0 if an error was encountered while computing the uptime
*/
static uint64_t ComputeProcessUptime();
/**
* When built with PRIntervalTime, a value of 0 means this instance
* is "null". Otherwise, the low 32 bits represent a PRIntervalTime,

View File

@ -24,7 +24,6 @@
#include "mozilla/TimeStamp.h"
#include "nsCRT.h"
#include "prenv.h"
#include "prprf.h"
// Estimate of the smallest duration of time we can measure.
@ -83,9 +82,6 @@ ClockResolutionNs()
namespace mozilla {
TimeStamp TimeStamp::sFirstTimeStamp;
TimeStamp TimeStamp::sProcessCreation;
double
TimeDuration::ToSeconds() const
{
@ -176,8 +172,8 @@ TimeStamp::Now(bool aHighResolution)
// Computes and returns the process uptime in microseconds.
// Returns 0 if an error was encountered.
static uint64_t
ComputeProcessUptime()
uint64_t
TimeStamp::ComputeProcessUptime()
{
struct timeval tv;
int rv = gettimeofday(&tv, NULL);
@ -212,42 +208,4 @@ ComputeProcessUptime()
return now - startTime;
}
TimeStamp
TimeStamp::ProcessCreation(bool& aIsInconsistent)
{
aIsInconsistent = false;
if (sProcessCreation.IsNull()) {
char *mozAppRestart = PR_GetEnv("MOZ_APP_RESTART");
TimeStamp ts;
if (mozAppRestart) {
ts = TimeStamp(nsCRT::atoll(mozAppRestart));
} else {
TimeStamp now = TimeStamp::Now();
uint64_t uptime = ComputeProcessUptime();
ts = now - TimeDuration::FromMicroseconds(uptime);
if ((ts > sFirstTimeStamp) || (uptime == 0)) {
// If the process creation timestamp was inconsistent replace it with the
// first one instead and notify that a telemetry error was detected.
aIsInconsistent = true;
ts = sFirstTimeStamp;
}
}
sProcessCreation = ts;
}
return sProcessCreation;
}
void
TimeStamp::RecordProcessRestart()
{
PR_SetEnv(PR_smprintf("MOZ_APP_RESTART=%lld", ClockTime()));
sProcessCreation = TimeStamp();
}
}
} // namespace mozilla

View File

@ -48,7 +48,6 @@
#include "mozilla/TimeStamp.h"
#include "nsCRT.h"
#include "prenv.h"
#include "prprf.h"
#include "prthread.h"
@ -132,9 +131,6 @@ ClockResolutionNs()
namespace mozilla {
TimeStamp TimeStamp::sFirstTimeStamp;
TimeStamp TimeStamp::sProcessCreation;
double
TimeDuration::ToSeconds() const
{
@ -283,11 +279,11 @@ ComputeProcessUptimeThread(void *aTime)
*uptime = ((threadJiffies - selfJiffies) * kNsPerSec) / hz;
}
// Computes and returns the process uptime in ns on Linux & its derivatives.
// Computes and returns the process uptime in us on Linux & its derivatives.
// Returns 0 if an error was encountered.
static uint64_t
ComputeProcessUptime()
uint64_t
TimeStamp::ComputeProcessUptime()
{
uint64_t uptime = 0;
PRThread *thread = PR_CreateThread(PR_USER_THREAD,
@ -300,17 +296,17 @@ ComputeProcessUptime()
PR_JoinThread(thread);
return uptime;
return uptime / kNsPerUs;
}
#elif defined(__DragonFly__) || defined(__FreeBSD__) \
|| defined(__NetBSD__) || defined(__OpenBSD__)
// Computes and returns the process uptime in ns on various BSD flavors.
// Computes and returns the process uptime in us on various BSD flavors.
// Returns 0 if an error was encountered.
static uint64_t
ComputeProcessUptime()
uint64_t
TimeStamp::ComputeProcessUptime()
{
struct timespec ts;
int rv = clock_gettime(CLOCK_REALTIME, &ts);
@ -345,55 +341,17 @@ ComputeProcessUptime()
if (startTime > now)
return 0;
return (now - startTime);
return (now - startTime) / kNsPerUs;
}
#else
static uint64_t
ComputeProcessUptime()
uint64_t
TimeStamp::ComputeProcessUptime()
{
return 0;
}
#endif
TimeStamp
TimeStamp::ProcessCreation(bool& aIsInconsistent)
{
aIsInconsistent = false;
if (sProcessCreation.IsNull()) {
char *mozAppRestart = PR_GetEnv("MOZ_APP_RESTART");
TimeStamp ts;
if (mozAppRestart) {
ts = TimeStamp(nsCRT::atoll(mozAppRestart));
} else {
TimeStamp now = TimeStamp::Now();
uint64_t uptime = ComputeProcessUptime();
ts = now - TimeDuration::FromMicroseconds(uptime / 1000);
if ((ts > sFirstTimeStamp) || (uptime == 0)) {
// If the process creation timestamp was inconsistent replace it with the
// first one instead and notify that a telemetry error was detected.
aIsInconsistent = true;
ts = sFirstTimeStamp;
}
}
sProcessCreation = ts;
}
return sProcessCreation;
}
void
TimeStamp::RecordProcessRestart()
{
PR_SetEnv(PR_smprintf("MOZ_APP_RESTART=%lld", ClockTimeNs()));
sProcessCreation = TimeStamp();
}
}
} // namespace mozilla

View File

@ -18,7 +18,6 @@
#include "nsCRT.h"
#include "prlog.h"
#include "prenv.h"
#include "prprf.h"
#include <stdio.h>
@ -183,9 +182,6 @@ static DWORD sLastGTCRollover = 0;
namespace mozilla {
TimeStamp TimeStamp::sFirstTimeStamp;
TimeStamp TimeStamp::sProcessCreation;
typedef ULONGLONG (WINAPI* GetTickCount64_t)();
static GetTickCount64_t sGetTickCount64 = nullptr;
@ -562,11 +558,11 @@ TimeStamp::Now(bool aHighResolution)
return TimeStamp(TimeStampValue(GTC, QPC, useQPC));
}
// Computes and returns the current process uptime in microseconds.
// Returns 0 if an error was encountered while computing the uptime.
// Computes and returns the process uptime in microseconds.
// Returns 0 if an error was encountered.
static uint64_t
ComputeProcessUptime()
uint64_t
TimeStamp::ComputeProcessUptime()
{
SYSTEMTIME nowSys;
GetSystemTime(&nowSys);
@ -595,41 +591,4 @@ ComputeProcessUptime()
return (nowUsec.QuadPart - startUsec.QuadPart) / 10ULL;
}
TimeStamp
TimeStamp::ProcessCreation(bool& aIsInconsistent)
{
aIsInconsistent = false;
if (sProcessCreation.IsNull()) {
char *mozAppRestart = PR_GetEnv("MOZ_APP_RESTART");
TimeStamp ts;
if (mozAppRestart) {
ts = TimeStamp(TimeStampValue(nsCRT::atoll(mozAppRestart), 0, false));
} else {
TimeStamp now = TimeStamp::Now();
uint64_t uptime = ComputeProcessUptime();
ts = now - TimeDuration::FromMicroseconds(static_cast<double>(uptime));
if ((ts > sFirstTimeStamp) || (uptime == 0)) {
// If the process creation timestamp was inconsistent replace it with the
// first one instead and notify that a telemetry error was detected.
aIsInconsistent = true;
ts = sFirstTimeStamp;
}
}
sProcessCreation = ts;
}
return sProcessCreation;
}
void
TimeStamp::RecordProcessRestart()
{
PR_SetEnv(PR_smprintf("MOZ_APP_RESTART=%lld", ms2mt(sGetTickCount64())));
sProcessCreation = TimeStamp();
}
} // namespace mozilla

View File

@ -95,6 +95,7 @@ CPP_SOURCES += [
'nsSupportsPrimitives.cpp',
'nsUnicharBuffer.cpp',
'nsVariant.cpp',
'TimeStamp.cpp',
]
if CONFIG['OS_ARCH'] == 'WINNT':