Line data Source code
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/. */
6 :
7 : /*
8 : * Implementation of the OS-independent methods of the TimeStamp class
9 : */
10 :
11 : #include "mozilla/TimeStamp.h"
12 : #include <stdio.h>
13 : #include <string.h>
14 :
15 : namespace mozilla {
16 :
17 : /**
18 : * Wrapper class used to initialize static data used by the TimeStamp class
19 : */
20 : struct TimeStampInitialization
21 : {
22 : /**
23 : * First timestamp taken when the class static initializers are run. This
24 : * timestamp is used to sanitize timestamps coming from different sources.
25 : */
26 : TimeStamp mFirstTimeStamp;
27 :
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.
32 : */
33 : TimeStamp mProcessCreation;
34 :
35 3 : TimeStampInitialization()
36 3 : {
37 3 : TimeStamp::Startup();
38 3 : mFirstTimeStamp = TimeStamp::Now();
39 3 : };
40 :
41 0 : ~TimeStampInitialization()
42 0 : {
43 0 : TimeStamp::Shutdown();
44 0 : };
45 : };
46 :
47 3 : static TimeStampInitialization sInitOnce;
48 :
49 : MFBT_API TimeStamp
50 782 : TimeStamp::ProcessCreation(bool* aIsInconsistent)
51 : {
52 782 : if (aIsInconsistent) {
53 13 : *aIsInconsistent = false;
54 : }
55 :
56 782 : if (sInitOnce.mProcessCreation.IsNull()) {
57 3 : char* mozAppRestart = getenv("MOZ_APP_RESTART");
58 3 : TimeStamp ts;
59 :
60 : /* When calling PR_SetEnv() with an empty value the existing variable may
61 : * be unset or set to the empty string depending on the underlying platform
62 : * thus we have to check if the variable is present and not empty. */
63 3 : if (mozAppRestart && (strcmp(mozAppRestart, "") != 0)) {
64 : /* Firefox was restarted, use the first time-stamp we've taken as the new
65 : * process startup time. */
66 0 : ts = sInitOnce.mFirstTimeStamp;
67 : } else {
68 3 : TimeStamp now = Now();
69 3 : uint64_t uptime = ComputeProcessUptime();
70 :
71 3 : ts = now - TimeDuration::FromMicroseconds(uptime);
72 :
73 3 : if ((ts > sInitOnce.mFirstTimeStamp) || (uptime == 0)) {
74 : /* If the process creation timestamp was inconsistent replace it with
75 : * the first one instead and notify that a telemetry error was
76 : * detected. */
77 0 : if (aIsInconsistent) {
78 0 : *aIsInconsistent = true;
79 : }
80 0 : ts = sInitOnce.mFirstTimeStamp;
81 : }
82 : }
83 :
84 3 : sInitOnce.mProcessCreation = ts;
85 : }
86 :
87 782 : return sInitOnce.mProcessCreation;
88 : }
89 :
90 : void
91 0 : TimeStamp::RecordProcessRestart()
92 : {
93 0 : sInitOnce.mProcessCreation = TimeStamp();
94 0 : }
95 :
96 9 : } // namespace mozilla
|