1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 * Implementation of the OS-independent methods of the TimeStamp class
11 #include "mozilla/Atomics.h"
12 #include "mozilla/TimeStamp.h"
20 * Wrapper class used to initialize static data used by the TimeStamp class
22 struct TimeStampInitialization
25 * First timestamp taken when the class static initializers are run. This
26 * timestamp is used to sanitize timestamps coming from different sources.
28 TimeStamp mFirstTimeStamp
;
31 * Timestamp representing the time when the process was created. This field
32 * is populated lazily the first time this information is required and is
33 * replaced every time the process is restarted.
35 TimeStamp mProcessCreation
;
37 TimeStampInitialization()
40 mFirstTimeStamp
= TimeStamp::Now();
43 ~TimeStampInitialization()
45 TimeStamp::Shutdown();
49 static bool sFuzzyfoxEnabled
;
52 TimeStamp::GetFuzzyfoxEnabled()
54 return sFuzzyfoxEnabled
;
58 TimeStamp::SetFuzzyfoxEnabled(bool aValue
)
60 sFuzzyfoxEnabled
= aValue
;
63 // These variables store the frozen time (as a TimeStamp) for FuzzyFox that
64 // will be reported if FuzzyFox is enabled.
65 // We overload the top bit of sCanonicalNow and sCanonicalGTC to
66 // indicate if a Timestamp is a fuzzed timestamp (bit set) or not
69 static Atomic
<uint64_t> sCanonicalGTC
;
70 static Atomic
<uint64_t> sCanonicalQPC
;
71 static Atomic
<bool> sCanonicalHasQPC
;
73 static Atomic
<uint64_t> sCanonicalNowTimeStamp
;
75 static Atomic
<int64_t> sCanonicalNowTime
;
76 // This variable stores the frozen time (as ms since the epoch) for FuzzyFox
77 // to report if FuzzyFox is enabled.
78 static TimeStampInitialization sInitOnce
;
81 TimeStamp::ProcessCreation(bool* aIsInconsistent
)
83 if (aIsInconsistent
) {
84 *aIsInconsistent
= false;
87 if (sInitOnce
.mProcessCreation
.IsNull()) {
88 char* mozAppRestart
= getenv("MOZ_APP_RESTART");
91 /* When calling PR_SetEnv() with an empty value the existing variable may
92 * be unset or set to the empty string depending on the underlying platform
93 * thus we have to check if the variable is present and not empty. */
94 if (mozAppRestart
&& (strcmp(mozAppRestart
, "") != 0)) {
95 /* Firefox was restarted, use the first time-stamp we've taken as the new
96 * process startup time. */
97 ts
= sInitOnce
.mFirstTimeStamp
;
99 TimeStamp now
= Now();
100 uint64_t uptime
= ComputeProcessUptime();
102 ts
= now
- TimeDuration::FromMicroseconds(uptime
);
104 if ((ts
> sInitOnce
.mFirstTimeStamp
) || (uptime
== 0)) {
105 /* If the process creation timestamp was inconsistent replace it with
106 * the first one instead and notify that a telemetry error was
108 if (aIsInconsistent
) {
109 *aIsInconsistent
= true;
111 ts
= sInitOnce
.mFirstTimeStamp
;
115 sInitOnce
.mProcessCreation
= ts
;
118 return sInitOnce
.mProcessCreation
;
122 TimeStamp::RecordProcessRestart()
124 sInitOnce
.mProcessCreation
= TimeStamp();
128 TimeStamp::NowFuzzy(TimeStampValue aValue
)
131 TimeStampValue canonicalNow
= TimeStampValue(sCanonicalGTC
, sCanonicalQPC
, sCanonicalHasQPC
, true);
133 TimeStampValue canonicalNow
= TimeStampValue(sCanonicalNowTimeStamp
);
136 if (TimeStamp::GetFuzzyfoxEnabled()) {
137 if(MOZ_LIKELY(!canonicalNow
.IsNull())) {
138 return TimeStamp(canonicalNow
);
141 // When we disable Fuzzyfox, time may goes backwards, so we need to make sure
143 else if (MOZ_UNLIKELY(canonicalNow
> aValue
)) {
144 return TimeStamp(canonicalNow
);
147 return TimeStamp(aValue
);
151 TimeStamp::UpdateFuzzyTimeStamp(TimeStamp aValue
)
154 sCanonicalGTC
= aValue
.mValue
.mGTC
;
155 sCanonicalQPC
= aValue
.mValue
.mQPC
;
156 sCanonicalHasQPC
= aValue
.mValue
.mHasQPC
;
158 sCanonicalNowTimeStamp
= aValue
.mValue
.mTimeStamp
;
163 TimeStamp::NowFuzzyTime()
165 return sCanonicalNowTime
;
169 TimeStamp::UpdateFuzzyTime(int64_t aValue
)
171 sCanonicalNowTime
= aValue
;
174 } // namespace mozilla