diff options
Diffstat (limited to 'mozglue/misc/TimeStamp.cpp')
-rw-r--r-- | mozglue/misc/TimeStamp.cpp | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/mozglue/misc/TimeStamp.cpp b/mozglue/misc/TimeStamp.cpp new file mode 100644 index 000000000..932b75c99 --- /dev/null +++ b/mozglue/misc/TimeStamp.cpp @@ -0,0 +1,92 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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 <stdio.h> +#include <string.h> + +namespace mozilla { + +/** + * Wrapper class used to initialize static data used by the TimeStamp class + */ +struct TimeStampInitialization +{ + /** + * First timestamp taken when the class static initializers are run. This + * timestamp is used to sanitize timestamps coming from different sources. + */ + TimeStamp mFirstTimeStamp; + + /** + * Timestamp representing the time when the process was created. This field + * is populated lazily the first time this information is required and is + * replaced every time the process is restarted. + */ + TimeStamp mProcessCreation; + + TimeStampInitialization() + { + TimeStamp::Startup(); + mFirstTimeStamp = TimeStamp::Now(); + }; + + ~TimeStampInitialization() + { + TimeStamp::Shutdown(); + }; +}; + +static TimeStampInitialization sInitOnce; + +MFBT_API TimeStamp +TimeStamp::ProcessCreation(bool& aIsInconsistent) +{ + aIsInconsistent = false; + + if (sInitOnce.mProcessCreation.IsNull()) { + char* mozAppRestart = 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. */ + ts = sInitOnce.mFirstTimeStamp; + } else { + TimeStamp now = Now(); + uint64_t uptime = ComputeProcessUptime(); + + ts = now - TimeDuration::FromMicroseconds(uptime); + + if ((ts > sInitOnce.mFirstTimeStamp) || (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 = sInitOnce.mFirstTimeStamp; + } + } + + sInitOnce.mProcessCreation = ts; + } + + return sInitOnce.mProcessCreation; +} + +void +TimeStamp::RecordProcessRestart() +{ + sInitOnce.mProcessCreation = TimeStamp(); +} + +} // namespace mozilla |