Bug 1874684 - Part 4: Prefer const references instead of copying Instant values....
[gecko.git] / mozglue / misc / TimeStamp.cpp
blobf77cf631323baa46ee8f4b10656682e964c0bfb4
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/. */
7 /*
8 * Implementation of the OS-independent methods of the TimeStamp class
9 */
11 #include "mozilla/TimeStamp.h"
12 #include "mozilla/Uptime.h"
13 #include <string.h>
14 #include <stdlib.h>
16 namespace mozilla {
18 /**
19 * Wrapper class used to initialize static data used by the TimeStamp class
21 struct TimeStampInitialization {
22 /**
23 * First timestamp taken when the class static initializers are run. This
24 * timestamp is used to sanitize timestamps coming from different sources.
26 TimeStamp mFirstTimeStamp;
28 /**
29 * Timestamp representing the time when the process was created. This field
30 * is populated lazily the first time this information is required and is
31 * replaced every time the process is restarted.
33 TimeStamp mProcessCreation;
35 TimeStampInitialization() {
36 TimeStamp::Startup();
37 mFirstTimeStamp = TimeStamp::Now();
38 // On Windows < 10, initializing the uptime requires `mFirstTimeStamp` to be
39 // valid.
40 mozilla::InitializeUptime();
43 ~TimeStampInitialization() { TimeStamp::Shutdown(); }
46 static TimeStampInitialization sInitOnce;
48 MFBT_API TimeStamp TimeStamp::ProcessCreation() {
49 if (sInitOnce.mProcessCreation.IsNull()) {
50 char* mozAppRestart = getenv("MOZ_APP_RESTART");
51 TimeStamp ts;
53 /* When calling PR_SetEnv() with an empty value the existing variable may
54 * be unset or set to the empty string depending on the underlying platform
55 * thus we have to check if the variable is present and not empty. */
56 if (mozAppRestart && (strcmp(mozAppRestart, "") != 0)) {
57 /* Firefox was restarted, use the first time-stamp we've taken as the new
58 * process startup time. */
59 ts = sInitOnce.mFirstTimeStamp;
60 } else {
61 TimeStamp now = Now();
62 uint64_t uptime = ComputeProcessUptime();
64 ts = now - TimeDuration::FromMicroseconds(static_cast<double>(uptime));
66 if ((ts > sInitOnce.mFirstTimeStamp) || (uptime == 0)) {
67 ts = sInitOnce.mFirstTimeStamp;
71 sInitOnce.mProcessCreation = ts;
74 return sInitOnce.mProcessCreation;
77 void TimeStamp::RecordProcessRestart() {
78 sInitOnce.mProcessCreation = TimeStamp();
81 MFBT_API TimeStamp TimeStamp::FirstTimeStamp() {
82 return sInitOnce.mFirstTimeStamp;
85 class TimeStampTests {
86 // Check that nullity is set/not set correctly.
87 static_assert(TimeStamp{TimeStampValue{0}}.IsNull());
88 static_assert(!TimeStamp{TimeStampValue{1}}.IsNull());
90 // Check that some very basic comparisons work correctly.
91 static constexpr uint64_t sMidTime = (uint64_t)1 << 63;
92 static_assert(TimeStampValue{sMidTime + 5} > TimeStampValue{sMidTime - 5});
93 static_assert(TimeStampValue{sMidTime + 5} >= TimeStampValue{sMidTime - 5});
94 static_assert(TimeStampValue{sMidTime - 5} < TimeStampValue{sMidTime + 5});
95 static_assert(TimeStampValue{sMidTime - 5} <= TimeStampValue{sMidTime + 5});
96 static_assert(TimeStampValue{sMidTime} == TimeStampValue{sMidTime});
97 static_assert(TimeStampValue{sMidTime} >= TimeStampValue{sMidTime});
98 static_assert(TimeStampValue{sMidTime} <= TimeStampValue{sMidTime});
99 static_assert(TimeStampValue{sMidTime - 5} != TimeStampValue{sMidTime + 5});
101 // Check that comparisons involving very large and very small TimeStampValue's
102 // work correctly. This may seem excessive, but these asserts would have
103 // failed in the past due to a comparison such as "a > b" being implemented as
104 // "<cast to signed 64-bit value>(a - b) > 0". When a-b didn't fit into a
105 // signed 64-bit value, this would have given an incorrect result.
106 static_assert(TimeStampValue{UINT64_MAX} > TimeStampValue{1});
107 static_assert(TimeStampValue{1} < TimeStampValue{UINT64_MAX});
109 // NOTE/TODO: It would be nice to add some additional tests here that involve
110 // arithmetic between TimeStamps and TimeDurations (and verifying some of the
111 // special behaviors in some cases such as not wrapping around below zero) but
112 // that is not possible right now because those operators are not constexpr.
115 } // namespace mozilla