diff options
Diffstat (limited to 'mozglue/misc/TimeStamp.cpp')
-rw-r--r-- | mozglue/misc/TimeStamp.cpp | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/mozglue/misc/TimeStamp.cpp b/mozglue/misc/TimeStamp.cpp new file mode 100644 index 0000000000..4133234617 --- /dev/null +++ b/mozglue/misc/TimeStamp.cpp @@ -0,0 +1,85 @@ +/* -*- 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 "mozilla/Uptime.h" +#include <string.h> +#include <stdlib.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(); + // On Windows < 10, initializing the uptime requires `mFirstTimeStamp` to be + // valid. + mozilla::InitializeUptime(); + }; + + ~TimeStampInitialization() { TimeStamp::Shutdown(); }; +}; + +static TimeStampInitialization sInitOnce; + +MFBT_API TimeStamp TimeStamp::ProcessCreation() { + 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(static_cast<double>(uptime)); + + if ((ts > sInitOnce.mFirstTimeStamp) || (uptime == 0)) { + ts = sInitOnce.mFirstTimeStamp; + } + } + + sInitOnce.mProcessCreation = ts; + } + + return sInitOnce.mProcessCreation; +} + +void TimeStamp::RecordProcessRestart() { + sInitOnce.mProcessCreation = TimeStamp(); +} + +MFBT_API TimeStamp TimeStamp::FirstTimeStamp() { + return sInitOnce.mFirstTimeStamp; +} + +} // namespace mozilla |