/* -*- 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 #include 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(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