Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dist/include/mozilla/TimeStamp.h
Line
Count
Source (jump to first uncovered line)
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
#ifndef mozilla_TimeStamp_h
8
#define mozilla_TimeStamp_h
9
10
#include <stdint.h>
11
#include <algorithm>  // for std::min, std::max
12
#include <ostream>
13
#include "mozilla/Assertions.h"
14
#include "mozilla/Attributes.h"
15
#include "mozilla/FloatingPoint.h"
16
#include "mozilla/TypeTraits.h"
17
#include "mozilla/Types.h"
18
19
namespace IPC {
20
template<typename T> struct ParamTraits;
21
} // namespace IPC
22
23
#ifdef XP_WIN
24
// defines TimeStampValue as a complex value keeping both
25
// GetTickCount and QueryPerformanceCounter values
26
#include "TimeStamp_windows.h"
27
#endif
28
29
namespace mozilla {
30
31
#ifndef XP_WIN
32
typedef uint64_t TimeStampValue;
33
#endif
34
35
class TimeStamp;
36
37
/**
38
 * Platform-specific implementation details of BaseTimeDuration.
39
 */
40
class BaseTimeDurationPlatformUtils
41
{
42
public:
43
  static MFBT_API double ToSeconds(int64_t aTicks);
44
  static MFBT_API double ToSecondsSigDigits(int64_t aTicks);
45
  static MFBT_API int64_t TicksFromMilliseconds(double aMilliseconds);
46
  static MFBT_API int64_t ResolutionInTicks();
47
};
48
49
/**
50
 * Instances of this class represent the length of an interval of time.
51
 * Negative durations are allowed, meaning the end is before the start.
52
 *
53
 * Internally the duration is stored as a int64_t in units of
54
 * PR_TicksPerSecond() when building with NSPR interval timers, or a
55
 * system-dependent unit when building with system clocks.  The
56
 * system-dependent unit must be constant, otherwise the semantics of
57
 * this class would be broken.
58
 *
59
 * The ValueCalculator template parameter determines how arithmetic
60
 * operations are performed on the integer count of ticks (mValue).
61
 */
62
template <typename ValueCalculator>
63
class BaseTimeDuration
64
{
65
public:
66
  // The default duration is 0.
67
74.2k
  constexpr BaseTimeDuration() : mValue(0) {}
mozilla::BaseTimeDuration<mozilla::TimeDurationValueCalculator>::BaseTimeDuration()
Line
Count
Source
67
74.2k
  constexpr BaseTimeDuration() : mValue(0) {}
Unexecuted instantiation: mozilla::BaseTimeDuration<mozilla::StickyTimeDurationValueCalculator>::BaseTimeDuration()
68
  // Allow construction using '0' as the initial value, for readability,
69
  // but no other numbers (so we don't have any implicit unit conversions).
70
  struct _SomethingVeryRandomHere;
71
  MOZ_IMPLICIT BaseTimeDuration(_SomethingVeryRandomHere* aZero) : mValue(0)
72
5.60k
  {
73
5.60k
    MOZ_ASSERT(!aZero, "Who's playing funny games here?");
74
5.60k
  }
mozilla::BaseTimeDuration<mozilla::TimeDurationValueCalculator>::BaseTimeDuration(mozilla::BaseTimeDuration<mozilla::TimeDurationValueCalculator>::_SomethingVeryRandomHere*)
Line
Count
Source
72
5.60k
  {
73
5.60k
    MOZ_ASSERT(!aZero, "Who's playing funny games here?");
74
5.60k
  }
Unexecuted instantiation: mozilla::BaseTimeDuration<mozilla::StickyTimeDurationValueCalculator>::BaseTimeDuration(mozilla::BaseTimeDuration<mozilla::StickyTimeDurationValueCalculator>::_SomethingVeryRandomHere*)
75
  // Default copy-constructor and assignment are OK
76
77
  // Converting copy-constructor and assignment operator
78
  template <typename E>
79
  explicit BaseTimeDuration(const BaseTimeDuration<E>& aOther)
80
    : mValue(aOther.mValue)
81
0
  { }
Unexecuted instantiation: mozilla::BaseTimeDuration<mozilla::StickyTimeDurationValueCalculator>::BaseTimeDuration<mozilla::TimeDurationValueCalculator>(mozilla::BaseTimeDuration<mozilla::TimeDurationValueCalculator> const&)
Unexecuted instantiation: mozilla::BaseTimeDuration<mozilla::TimeDurationValueCalculator>::BaseTimeDuration<mozilla::StickyTimeDurationValueCalculator>(mozilla::BaseTimeDuration<mozilla::StickyTimeDurationValueCalculator> const&)
82
83
  template <typename E>
84
  BaseTimeDuration& operator=(const BaseTimeDuration<E>& aOther)
85
0
  {
86
0
    mValue = aOther.mValue;
87
0
    return *this;
88
0
  }
Unexecuted instantiation: mozilla::BaseTimeDuration<mozilla::StickyTimeDurationValueCalculator>& mozilla::BaseTimeDuration<mozilla::StickyTimeDurationValueCalculator>::operator=<mozilla::TimeDurationValueCalculator>(mozilla::BaseTimeDuration<mozilla::TimeDurationValueCalculator> const&)
Unexecuted instantiation: mozilla::BaseTimeDuration<mozilla::TimeDurationValueCalculator>& mozilla::BaseTimeDuration<mozilla::TimeDurationValueCalculator>::operator=<mozilla::StickyTimeDurationValueCalculator>(mozilla::BaseTimeDuration<mozilla::StickyTimeDurationValueCalculator> const&)
89
90
  double ToSeconds() const
91
3.11k
  {
92
3.11k
    if (mValue == INT64_MAX) {
93
0
      return PositiveInfinity<double>();
94
0
    }
95
3.11k
    if (mValue == INT64_MIN) {
96
0
      return NegativeInfinity<double>();
97
0
    }
98
3.11k
    return BaseTimeDurationPlatformUtils::ToSeconds(mValue);
99
3.11k
  }
mozilla::BaseTimeDuration<mozilla::TimeDurationValueCalculator>::ToSeconds() const
Line
Count
Source
91
3.11k
  {
92
3.11k
    if (mValue == INT64_MAX) {
93
0
      return PositiveInfinity<double>();
94
0
    }
95
3.11k
    if (mValue == INT64_MIN) {
96
0
      return NegativeInfinity<double>();
97
0
    }
98
3.11k
    return BaseTimeDurationPlatformUtils::ToSeconds(mValue);
99
3.11k
  }
Unexecuted instantiation: mozilla::BaseTimeDuration<mozilla::StickyTimeDurationValueCalculator>::ToSeconds() const
100
  // Return a duration value that includes digits of time we think to
101
  // be significant.  This method should be used when displaying a
102
  // time to humans.
103
  double ToSecondsSigDigits() const
104
0
  {
105
0
    if (mValue == INT64_MAX) {
106
0
      return PositiveInfinity<double>();
107
0
    }
108
0
    if (mValue == INT64_MIN) {
109
0
      return NegativeInfinity<double>();
110
0
    }
111
0
    return BaseTimeDurationPlatformUtils::ToSecondsSigDigits(mValue);
112
0
  }
113
3.01k
  double ToMilliseconds() const { return ToSeconds() * 1000.0; }
mozilla::BaseTimeDuration<mozilla::TimeDurationValueCalculator>::ToMilliseconds() const
Line
Count
Source
113
3.01k
  double ToMilliseconds() const { return ToSeconds() * 1000.0; }
Unexecuted instantiation: mozilla::BaseTimeDuration<mozilla::StickyTimeDurationValueCalculator>::ToMilliseconds() const
114
2.26k
  double ToMicroseconds() const { return ToMilliseconds() * 1000.0; }
115
116
  // Using a double here is safe enough; with 53 bits we can represent
117
  // durations up to over 280,000 years exactly.  If the units of
118
  // mValue do not allow us to represent durations of that length,
119
  // long durations are clamped to the max/min representable value
120
  // instead of overflowing.
121
  static inline BaseTimeDuration FromSeconds(double aSeconds)
122
118
  {
123
118
    return FromMilliseconds(aSeconds * 1000.0);
124
118
  }
125
  static BaseTimeDuration FromMilliseconds(double aMilliseconds)
126
586
  {
127
586
    if (aMilliseconds == PositiveInfinity<double>()) {
128
0
      return Forever();
129
0
    }
130
586
    if (aMilliseconds == NegativeInfinity<double>()) {
131
0
      return FromTicks(INT64_MIN);
132
0
    }
133
586
    return FromTicks(
134
586
      BaseTimeDurationPlatformUtils::TicksFromMilliseconds(aMilliseconds));
135
586
  }
mozilla::BaseTimeDuration<mozilla::TimeDurationValueCalculator>::FromMilliseconds(double)
Line
Count
Source
126
586
  {
127
586
    if (aMilliseconds == PositiveInfinity<double>()) {
128
0
      return Forever();
129
0
    }
130
586
    if (aMilliseconds == NegativeInfinity<double>()) {
131
0
      return FromTicks(INT64_MIN);
132
0
    }
133
586
    return FromTicks(
134
586
      BaseTimeDurationPlatformUtils::TicksFromMilliseconds(aMilliseconds));
135
586
  }
Unexecuted instantiation: mozilla::BaseTimeDuration<mozilla::StickyTimeDurationValueCalculator>::FromMilliseconds(double)
136
  static inline BaseTimeDuration FromMicroseconds(double aMicroseconds)
137
98
  {
138
98
    return FromMilliseconds(aMicroseconds / 1000.0);
139
98
  }
140
141
  static constexpr BaseTimeDuration Forever()
142
3.00k
  {
143
3.00k
    return FromTicks(INT64_MAX);
144
3.00k
  }
mozilla::BaseTimeDuration<mozilla::TimeDurationValueCalculator>::Forever()
Line
Count
Source
142
3.00k
  {
143
3.00k
    return FromTicks(INT64_MAX);
144
3.00k
  }
Unexecuted instantiation: mozilla::BaseTimeDuration<mozilla::StickyTimeDurationValueCalculator>::Forever()
145
146
  BaseTimeDuration operator+(const BaseTimeDuration& aOther) const
147
0
  {
148
0
    return FromTicks(ValueCalculator::Add(mValue, aOther.mValue));
149
0
  }
Unexecuted instantiation: mozilla::BaseTimeDuration<mozilla::StickyTimeDurationValueCalculator>::operator+(mozilla::BaseTimeDuration<mozilla::StickyTimeDurationValueCalculator> const&) const
Unexecuted instantiation: mozilla::BaseTimeDuration<mozilla::TimeDurationValueCalculator>::operator+(mozilla::BaseTimeDuration<mozilla::TimeDurationValueCalculator> const&) const
150
  BaseTimeDuration operator-(const BaseTimeDuration& aOther) const
151
96
  {
152
96
    return FromTicks(ValueCalculator::Subtract(mValue, aOther.mValue));
153
96
  }
Unexecuted instantiation: mozilla::BaseTimeDuration<mozilla::StickyTimeDurationValueCalculator>::operator-(mozilla::BaseTimeDuration<mozilla::StickyTimeDurationValueCalculator> const&) const
mozilla::BaseTimeDuration<mozilla::TimeDurationValueCalculator>::operator-(mozilla::BaseTimeDuration<mozilla::TimeDurationValueCalculator> const&) const
Line
Count
Source
151
96
  {
152
96
    return FromTicks(ValueCalculator::Subtract(mValue, aOther.mValue));
153
96
  }
154
  BaseTimeDuration& operator+=(const BaseTimeDuration& aOther)
155
13.5k
  {
156
13.5k
    mValue = ValueCalculator::Add(mValue, aOther.mValue);
157
13.5k
    return *this;
158
13.5k
  }
Unexecuted instantiation: mozilla::BaseTimeDuration<mozilla::StickyTimeDurationValueCalculator>::operator+=(mozilla::BaseTimeDuration<mozilla::StickyTimeDurationValueCalculator> const&)
mozilla::BaseTimeDuration<mozilla::TimeDurationValueCalculator>::operator+=(mozilla::BaseTimeDuration<mozilla::TimeDurationValueCalculator> const&)
Line
Count
Source
155
13.5k
  {
156
13.5k
    mValue = ValueCalculator::Add(mValue, aOther.mValue);
157
13.5k
    return *this;
158
13.5k
  }
159
  BaseTimeDuration& operator-=(const BaseTimeDuration& aOther)
160
7.18k
  {
161
7.18k
    mValue = ValueCalculator::Subtract(mValue, aOther.mValue);
162
7.18k
    return *this;
163
7.18k
  }
Unexecuted instantiation: mozilla::BaseTimeDuration<mozilla::StickyTimeDurationValueCalculator>::operator-=(mozilla::BaseTimeDuration<mozilla::StickyTimeDurationValueCalculator> const&)
mozilla::BaseTimeDuration<mozilla::TimeDurationValueCalculator>::operator-=(mozilla::BaseTimeDuration<mozilla::TimeDurationValueCalculator> const&)
Line
Count
Source
160
7.18k
  {
161
7.18k
    mValue = ValueCalculator::Subtract(mValue, aOther.mValue);
162
7.18k
    return *this;
163
7.18k
  }
164
  BaseTimeDuration operator-() const
165
0
  {
166
0
    // We don't just use FromTicks(ValueCalculator::Subtract(0, mValue))
167
0
    // since that won't give the correct result for -TimeDuration::Forever().
168
0
    int64_t ticks;
169
0
    if (mValue == INT64_MAX) {
170
0
      ticks = INT64_MIN;
171
0
    } else if (mValue == INT64_MIN) {
172
0
      ticks = INT64_MAX;
173
0
    } else {
174
0
      ticks = -mValue;
175
0
    }
176
0
177
0
    return FromTicks(ticks);
178
0
  }
179
180
  static BaseTimeDuration Max(const BaseTimeDuration& aA,
181
                              const BaseTimeDuration& aB)
182
0
  {
183
0
    return FromTicks(std::max(aA.mValue, aB.mValue));
184
0
  }
185
  static BaseTimeDuration Min(const BaseTimeDuration& aA,
186
                              const BaseTimeDuration& aB)
187
0
  {
188
0
    return FromTicks(std::min(aA.mValue, aB.mValue));
189
0
  }
190
191
private:
192
  // Block double multiplier (slower, imprecise if long duration) - Bug 853398.
193
  // If required, use MultDouble explicitly and with care.
194
  BaseTimeDuration operator*(const double aMultiplier) const = delete;
195
196
  // Block double divisor (for the same reason, and because dividing by
197
  // fractional values would otherwise invoke the int64_t variant, and rounding
198
  // the passed argument can then cause divide-by-zero) - Bug 1147491.
199
  BaseTimeDuration operator/(const double aDivisor) const = delete;
200
201
public:
202
  BaseTimeDuration MultDouble(double aMultiplier) const
203
0
  {
204
0
    return FromTicks(ValueCalculator::Multiply(mValue, aMultiplier));
205
0
  }
Unexecuted instantiation: mozilla::BaseTimeDuration<mozilla::StickyTimeDurationValueCalculator>::MultDouble(double) const
Unexecuted instantiation: mozilla::BaseTimeDuration<mozilla::TimeDurationValueCalculator>::MultDouble(double) const
206
  BaseTimeDuration operator*(const int32_t aMultiplier) const
207
3
  {
208
3
    return FromTicks(ValueCalculator::Multiply(mValue, aMultiplier));
209
3
  }
210
  BaseTimeDuration operator*(const uint32_t aMultiplier) const
211
0
  {
212
0
    return FromTicks(ValueCalculator::Multiply(mValue, aMultiplier));
213
0
  }
214
  BaseTimeDuration operator*(const int64_t aMultiplier) const
215
  {
216
    return FromTicks(ValueCalculator::Multiply(mValue, aMultiplier));
217
  }
218
  BaseTimeDuration operator*(const uint64_t aMultiplier) const
219
  {
220
    if (aMultiplier > INT64_MAX) {
221
      return Forever();
222
    }
223
    return FromTicks(ValueCalculator::Multiply(mValue, aMultiplier));
224
  }
225
  BaseTimeDuration operator/(const int64_t aDivisor) const
226
0
  {
227
0
    MOZ_ASSERT(aDivisor != 0, "Division by zero");
228
0
    return FromTicks(ValueCalculator::Divide(mValue, aDivisor));
229
0
  }
230
  double operator/(const BaseTimeDuration& aOther) const
231
32
  {
232
32
    MOZ_ASSERT(aOther.mValue != 0, "Division by zero");
233
32
    return ValueCalculator::DivideDouble(mValue, aOther.mValue);
234
32
  }
Unexecuted instantiation: mozilla::BaseTimeDuration<mozilla::StickyTimeDurationValueCalculator>::operator/(mozilla::BaseTimeDuration<mozilla::StickyTimeDurationValueCalculator> const&) const
mozilla::BaseTimeDuration<mozilla::TimeDurationValueCalculator>::operator/(mozilla::BaseTimeDuration<mozilla::TimeDurationValueCalculator> const&) const
Line
Count
Source
231
32
  {
232
32
    MOZ_ASSERT(aOther.mValue != 0, "Division by zero");
233
32
    return ValueCalculator::DivideDouble(mValue, aOther.mValue);
234
32
  }
235
  BaseTimeDuration operator%(const BaseTimeDuration& aOther) const
236
0
  {
237
0
    MOZ_ASSERT(aOther.mValue != 0, "Division by zero");
238
0
    return FromTicks(ValueCalculator::Modulo(mValue, aOther.mValue));
239
0
  }
240
241
  template<typename E>
242
  bool operator<(const BaseTimeDuration<E>& aOther) const
243
7.13k
  {
244
7.13k
    return mValue < aOther.mValue;
245
7.13k
  }
bool mozilla::BaseTimeDuration<mozilla::TimeDurationValueCalculator>::operator< <mozilla::TimeDurationValueCalculator>(mozilla::BaseTimeDuration<mozilla::TimeDurationValueCalculator> const&) const
Line
Count
Source
243
7.13k
  {
244
7.13k
    return mValue < aOther.mValue;
245
7.13k
  }
Unexecuted instantiation: bool mozilla::BaseTimeDuration<mozilla::StickyTimeDurationValueCalculator>::operator< <mozilla::StickyTimeDurationValueCalculator>(mozilla::BaseTimeDuration<mozilla::StickyTimeDurationValueCalculator> const&) const
Unexecuted instantiation: bool mozilla::BaseTimeDuration<mozilla::TimeDurationValueCalculator>::operator< <mozilla::StickyTimeDurationValueCalculator>(mozilla::BaseTimeDuration<mozilla::StickyTimeDurationValueCalculator> const&) const
246
  template<typename E>
247
  bool operator<=(const BaseTimeDuration<E>& aOther) const
248
0
  {
249
0
    return mValue <= aOther.mValue;
250
0
  }
251
  template<typename E>
252
  bool operator>=(const BaseTimeDuration<E>& aOther) const
253
346
  {
254
346
    return mValue >= aOther.mValue;
255
346
  }
bool mozilla::BaseTimeDuration<mozilla::TimeDurationValueCalculator>::operator>=<mozilla::TimeDurationValueCalculator>(mozilla::BaseTimeDuration<mozilla::TimeDurationValueCalculator> const&) const
Line
Count
Source
253
346
  {
254
346
    return mValue >= aOther.mValue;
255
346
  }
Unexecuted instantiation: bool mozilla::BaseTimeDuration<mozilla::TimeDurationValueCalculator>::operator>=<mozilla::StickyTimeDurationValueCalculator>(mozilla::BaseTimeDuration<mozilla::StickyTimeDurationValueCalculator> const&) const
256
  template<typename E>
257
  bool operator>(const BaseTimeDuration<E>& aOther) const
258
5.29k
  {
259
5.29k
    return mValue > aOther.mValue;
260
5.29k
  }
bool mozilla::BaseTimeDuration<mozilla::TimeDurationValueCalculator>::operator><mozilla::TimeDurationValueCalculator>(mozilla::BaseTimeDuration<mozilla::TimeDurationValueCalculator> const&) const
Line
Count
Source
258
5.29k
  {
259
5.29k
    return mValue > aOther.mValue;
260
5.29k
  }
Unexecuted instantiation: bool mozilla::BaseTimeDuration<mozilla::TimeDurationValueCalculator>::operator><mozilla::StickyTimeDurationValueCalculator>(mozilla::BaseTimeDuration<mozilla::StickyTimeDurationValueCalculator> const&) const
261
  template<typename E>
262
  bool operator==(const BaseTimeDuration<E>& aOther) const
263
1.50k
  {
264
1.50k
    return mValue == aOther.mValue;
265
1.50k
  }
bool mozilla::BaseTimeDuration<mozilla::TimeDurationValueCalculator>::operator==<mozilla::TimeDurationValueCalculator>(mozilla::BaseTimeDuration<mozilla::TimeDurationValueCalculator> const&) const
Line
Count
Source
263
1.50k
  {
264
1.50k
    return mValue == aOther.mValue;
265
1.50k
  }
Unexecuted instantiation: bool mozilla::BaseTimeDuration<mozilla::StickyTimeDurationValueCalculator>::operator==<mozilla::TimeDurationValueCalculator>(mozilla::BaseTimeDuration<mozilla::TimeDurationValueCalculator> const&) const
Unexecuted instantiation: bool mozilla::BaseTimeDuration<mozilla::TimeDurationValueCalculator>::operator==<mozilla::StickyTimeDurationValueCalculator>(mozilla::BaseTimeDuration<mozilla::StickyTimeDurationValueCalculator> const&) const
Unexecuted instantiation: bool mozilla::BaseTimeDuration<mozilla::StickyTimeDurationValueCalculator>::operator==<mozilla::StickyTimeDurationValueCalculator>(mozilla::BaseTimeDuration<mozilla::StickyTimeDurationValueCalculator> const&) const
266
  template<typename E>
267
  bool operator!=(const BaseTimeDuration<E>& aOther) const
268
3
  {
269
3
    return mValue != aOther.mValue;
270
3
  }
Unexecuted instantiation: bool mozilla::BaseTimeDuration<mozilla::StickyTimeDurationValueCalculator>::operator!=<mozilla::TimeDurationValueCalculator>(mozilla::BaseTimeDuration<mozilla::TimeDurationValueCalculator> const&) const
bool mozilla::BaseTimeDuration<mozilla::TimeDurationValueCalculator>::operator!=<mozilla::TimeDurationValueCalculator>(mozilla::BaseTimeDuration<mozilla::TimeDurationValueCalculator> const&) const
Line
Count
Source
268
3
  {
269
3
    return mValue != aOther.mValue;
270
3
  }
271
  bool IsZero() const
272
12.6k
  {
273
12.6k
    return mValue == 0;
274
12.6k
  }
Unexecuted instantiation: mozilla::BaseTimeDuration<mozilla::StickyTimeDurationValueCalculator>::IsZero() const
mozilla::BaseTimeDuration<mozilla::TimeDurationValueCalculator>::IsZero() const
Line
Count
Source
272
12.6k
  {
273
12.6k
    return mValue == 0;
274
12.6k
  }
275
  explicit operator bool() const
276
0
  {
277
0
    return mValue != 0;
278
0
  }
Unexecuted instantiation: mozilla::BaseTimeDuration<mozilla::StickyTimeDurationValueCalculator>::operator bool() const
Unexecuted instantiation: mozilla::BaseTimeDuration<mozilla::TimeDurationValueCalculator>::operator bool() const
279
280
  friend std::ostream& operator<<(std::ostream& aStream,
281
0
                                  const BaseTimeDuration& aDuration) {
282
0
    return aStream << aDuration.ToMilliseconds() << " ms";
283
0
  }
284
285
  // Return a best guess at the system's current timing resolution,
286
  // which might be variable.  BaseTimeDurations below this order of
287
  // magnitude are meaningless, and those at the same order of
288
  // magnitude or just above are suspect.
289
0
  static BaseTimeDuration Resolution() {
290
0
    return FromTicks(BaseTimeDurationPlatformUtils::ResolutionInTicks());
291
0
  }
292
293
  // We could define additional operators here:
294
  // -- convert to/from other time units
295
  // -- scale duration by a float
296
  // but let's do that on demand.
297
  // Comparing durations for equality will only lead to bugs on
298
  // platforms with high-resolution timers.
299
300
private:
301
  friend class TimeStamp;
302
  friend struct IPC::ParamTraits<mozilla::BaseTimeDuration<ValueCalculator>>;
303
  template <typename>
304
  friend class BaseTimeDuration;
305
306
  static BaseTimeDuration FromTicks(int64_t aTicks)
307
8.43k
  {
308
8.43k
    BaseTimeDuration t;
309
8.43k
    t.mValue = aTicks;
310
8.43k
    return t;
311
8.43k
  }
mozilla::BaseTimeDuration<mozilla::TimeDurationValueCalculator>::FromTicks(long)
Line
Count
Source
307
8.43k
  {
308
8.43k
    BaseTimeDuration t;
309
8.43k
    t.mValue = aTicks;
310
8.43k
    return t;
311
8.43k
  }
Unexecuted instantiation: mozilla::BaseTimeDuration<mozilla::StickyTimeDurationValueCalculator>::FromTicks(long)
312
313
  static BaseTimeDuration FromTicks(double aTicks)
314
  {
315
    // NOTE: this MUST be a >= test, because int64_t(double(INT64_MAX))
316
    // overflows and gives INT64_MIN.
317
    if (aTicks >= double(INT64_MAX)) {
318
      return FromTicks(INT64_MAX);
319
    }
320
321
    // This MUST be a <= test.
322
    if (aTicks <= double(INT64_MIN)) {
323
      return FromTicks(INT64_MIN);
324
    }
325
326
    return FromTicks(int64_t(aTicks));
327
  }
328
329
  // Duration, result is implementation-specific difference of two TimeStamps
330
  int64_t mValue;
331
};
332
333
/**
334
 * Perform arithmetic operations on the value of a BaseTimeDuration without
335
 * doing strict checks on the range of values.
336
 */
337
class TimeDurationValueCalculator
338
{
339
public:
340
  static int64_t Add(int64_t aA, int64_t aB) { return aA + aB; }
341
  static int64_t Subtract(int64_t aA, int64_t aB) { return aA - aB; }
342
343
  template <typename T>
344
  static int64_t Multiply(int64_t aA, T aB)
345
3
  {
346
3
    static_assert(IsIntegral<T>::value,
347
3
                  "Using integer multiplication routine with non-integer type."
348
3
                  " Further specialization required");
349
3
    return aA * static_cast<int64_t>(aB);
350
3
  }
Unexecuted instantiation: long mozilla::TimeDurationValueCalculator::Multiply<unsigned int>(long, unsigned int)
long mozilla::TimeDurationValueCalculator::Multiply<int>(long, int)
Line
Count
Source
345
3
  {
346
3
    static_assert(IsIntegral<T>::value,
347
3
                  "Using integer multiplication routine with non-integer type."
348
3
                  " Further specialization required");
349
3
    return aA * static_cast<int64_t>(aB);
350
3
  }
351
352
0
  static int64_t Divide(int64_t aA, int64_t aB) { return aA / aB; }
353
  static double DivideDouble(int64_t aA, int64_t aB)
354
  {
355
    return static_cast<double>(aA) / aB;
356
  }
357
0
  static int64_t Modulo(int64_t aA, int64_t aB) { return aA % aB; }
358
};
359
360
template <>
361
inline int64_t
362
TimeDurationValueCalculator::Multiply<double>(int64_t aA, double aB)
363
0
{
364
0
  return static_cast<int64_t>(aA * aB);
365
0
}
366
367
/**
368
 * Specialization of BaseTimeDuration that uses TimeDurationValueCalculator for
369
 * arithmetic on the mValue member.
370
 *
371
 * Use this class for time durations that are *not* expected to hold values of
372
 * Forever (or the negative equivalent) or when such time duration are *not*
373
 * expected to be used in arithmetic operations.
374
 */
375
typedef BaseTimeDuration<TimeDurationValueCalculator> TimeDuration;
376
377
/**
378
 * Instances of this class represent moments in time, or a special
379
 * "null" moment. We do not use the non-monotonic system clock or
380
 * local time, since they can be reset, causing apparent backward
381
 * travel in time, which can confuse algorithms. Instead we measure
382
 * elapsed time according to the system.  This time can never go
383
 * backwards (i.e. it never wraps around, at least not in less than
384
 * five million years of system elapsed time). It might not advance
385
 * while the system is sleeping. If TimeStamp::SetNow() is not called
386
 * at all for hours or days, we might not notice the passage of some
387
 * of that time.
388
 *
389
 * We deliberately do not expose a way to convert TimeStamps to some
390
 * particular unit. All you can do is compute a difference between two
391
 * TimeStamps to get a TimeDuration. You can also add a TimeDuration
392
 * to a TimeStamp to get a new TimeStamp. You can't do something
393
 * meaningless like add two TimeStamps.
394
 *
395
 * Internally this is implemented as either a wrapper around
396
 *   - high-resolution, monotonic, system clocks if they exist on this
397
 *     platform
398
 *   - PRIntervalTime otherwise.  We detect wraparounds of
399
 *     PRIntervalTime and work around them.
400
 *
401
 * This class is similar to C++11's time_point, however it is
402
 * explicitly nullable and provides an IsNull() method. time_point
403
 * is initialized to the clock's epoch and provides a
404
 * time_since_epoch() method that functions similiarly. i.e.
405
 * t.IsNull() is equivalent to t.time_since_epoch() == decltype(t)::duration::zero();
406
 *
407
 * Note that, since TimeStamp objects are small, prefer to pass them by value
408
 * unless there is a specific reason not to do so.
409
 */
410
class TimeStamp
411
{
412
public:
413
  /**
414
   * Initialize to the "null" moment
415
   */
416
5.14k
  constexpr TimeStamp() : mValue(0) {}
417
  // Default copy-constructor and assignment are OK
418
419
  /**
420
   * The system timestamps are the same as the TimeStamp
421
   * retrieved by mozilla::TimeStamp. Since we need this for
422
   * vsync timestamps, we enable the creation of mozilla::TimeStamps
423
   * on platforms that support vsync aligned refresh drivers / compositors
424
   * Verified true as of Jan 31, 2015: B2G and OS X
425
   * False on Windows 7
426
   * Android's event time uses CLOCK_MONOTONIC via SystemClock.uptimeMilles.
427
   * So it is same value of TimeStamp posix implementation.
428
   * Wayland/GTK event time also uses CLOCK_MONOTONIC on Weston/Mutter
429
   * compositors.
430
   * UNTESTED ON OTHER PLATFORMS
431
   */
432
#if defined(XP_DARWIN) || defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GTK)
433
  static TimeStamp FromSystemTime(int64_t aSystemTime)
434
0
  {
435
0
    static_assert(sizeof(aSystemTime) == sizeof(TimeStampValue),
436
0
                  "System timestamp should be same units as TimeStampValue");
437
0
    return TimeStamp(aSystemTime);
438
0
  }
439
#endif
440
441
  /**
442
   * Return true if this is the "null" moment
443
   */
444
2.60k
  bool IsNull() const { return mValue == 0; }
445
446
  /**
447
   * Return true if this is not the "null" moment, may be used in tests, e.g.:
448
   * |if (timestamp) { ... }|
449
   */
450
  explicit operator bool() const
451
0
  {
452
0
    return mValue != 0;
453
0
  }
454
455
  /**
456
   * Return a timestamp reflecting the current elapsed system time. This
457
   * is monotonically increasing (i.e., does not decrease) over the
458
   * lifetime of this process' XPCOM session.
459
   *
460
   * Now() is trying to ensure the best possible precision on each platform,
461
   * at least one millisecond.
462
   *
463
   * NowLoRes() has been introduced to workaround performance problems of
464
   * QueryPerformanceCounter on the Windows platform.  NowLoRes() is giving
465
   * lower precision, usually 15.6 ms, but with very good performance benefit.
466
   * Use it for measurements of longer times, like >200ms timeouts.
467
   */
468
8.12k
  static TimeStamp Now() { return Now(true); }
469
  static TimeStamp NowLoRes() { return Now(false); }
470
471
  /**
472
   * Return a timestamp representing the time when the current process was
473
   * created which will be comparable with other timestamps taken with this
474
   * class. If the actual process creation time is detected to be inconsistent
475
   * the @a aIsInconsistent parameter will be set to true, the returned
476
   * timestamp however will still be valid though inaccurate.
477
   *
478
   * @param aIsInconsistent If non-null, set to true if an inconsistency was
479
   * detected in the process creation time
480
   * @returns A timestamp representing the time when the process was created,
481
   * this timestamp is always valid even when errors are reported
482
   */
483
  static MFBT_API TimeStamp ProcessCreation(bool* aIsInconsistent = nullptr);
484
485
  /**
486
   * Records a process restart. After this call ProcessCreation() will return
487
   * the time when the browser was restarted instead of the actual time when
488
   * the process was created.
489
   */
490
  static MFBT_API void RecordProcessRestart();
491
492
  /**
493
   * Compute the difference between two timestamps. Both must be non-null.
494
   */
495
  TimeDuration operator-(const TimeStamp& aOther) const
496
4.74k
  {
497
4.74k
    MOZ_ASSERT(!IsNull(), "Cannot compute with a null value");
498
4.74k
    MOZ_ASSERT(!aOther.IsNull(), "Cannot compute with aOther null value");
499
4.74k
    static_assert(-INT64_MAX > INT64_MIN, "int64_t sanity check");
500
4.74k
    int64_t ticks = int64_t(mValue - aOther.mValue);
501
4.74k
    // Check for overflow.
502
4.74k
    if (mValue > aOther.mValue) {
503
4.59k
      if (ticks < 0) {
504
0
        ticks = INT64_MAX;
505
0
      }
506
4.59k
    } else {
507
146
      if (ticks > 0) {
508
0
        ticks = INT64_MIN;
509
0
      }
510
146
    }
511
4.74k
    return TimeDuration::FromTicks(ticks);
512
4.74k
  }
513
514
  TimeStamp operator+(const TimeDuration& aOther) const
515
  {
516
    TimeStamp result = *this;
517
    result += aOther;
518
    return result;
519
  }
520
  TimeStamp operator-(const TimeDuration& aOther) const
521
3
  {
522
3
    TimeStamp result = *this;
523
3
    result -= aOther;
524
3
    return result;
525
3
  }
526
  TimeStamp& operator+=(const TimeDuration& aOther)
527
228
  {
528
228
    MOZ_ASSERT(!IsNull(), "Cannot compute with a null value");
529
228
    TimeStampValue value = mValue + aOther.mValue;
530
228
    // Check for underflow.
531
228
    // (We don't check for overflow because it's not obvious what the error
532
228
    //  behavior should be in that case.)
533
228
    if (aOther.mValue < 0 && value > mValue) {
534
0
      value = 0;
535
0
    }
536
228
    mValue = value;
537
228
    return *this;
538
228
  }
539
  TimeStamp& operator-=(const TimeDuration& aOther)
540
3
  {
541
3
    MOZ_ASSERT(!IsNull(), "Cannot compute with a null value");
542
3
    TimeStampValue value = mValue - aOther.mValue;
543
3
    // Check for underflow.
544
3
    // (We don't check for overflow because it's not obvious what the error
545
3
    //  behavior should be in that case.)
546
3
    if (aOther.mValue > 0 && value > mValue) {
547
0
      value = 0;
548
0
    }
549
3
    mValue = value;
550
3
    return *this;
551
3
  }
552
553
  bool operator<(const TimeStamp& aOther) const
554
3.85k
  {
555
3.85k
    MOZ_ASSERT(!IsNull(), "Cannot compute with a null value");
556
3.85k
    MOZ_ASSERT(!aOther.IsNull(), "Cannot compute with aOther null value");
557
3.85k
    return mValue < aOther.mValue;
558
3.85k
  }
559
  bool operator<=(const TimeStamp& aOther) const
560
0
  {
561
0
    MOZ_ASSERT(!IsNull(), "Cannot compute with a null value");
562
0
    MOZ_ASSERT(!aOther.IsNull(), "Cannot compute with aOther null value");
563
0
    return mValue <= aOther.mValue;
564
0
  }
Unexecuted instantiation: mozilla::TimeStamp::operator<=(mozilla::TimeStamp const&) const
Unexecuted instantiation: mozilla::TimeStamp::operator<=(mozilla::TimeStamp const&) const
565
  bool operator>=(const TimeStamp& aOther) const
566
1.46k
  {
567
1.46k
    MOZ_ASSERT(!IsNull(), "Cannot compute with a null value");
568
1.46k
    MOZ_ASSERT(!aOther.IsNull(), "Cannot compute with aOther null value");
569
1.46k
    return mValue >= aOther.mValue;
570
1.46k
  }
571
  bool operator>(const TimeStamp& aOther) const
572
29
  {
573
29
    MOZ_ASSERT(!IsNull(), "Cannot compute with a null value");
574
29
    MOZ_ASSERT(!aOther.IsNull(), "Cannot compute with aOther null value");
575
29
    return mValue > aOther.mValue;
576
29
  }
577
  bool operator==(const TimeStamp& aOther) const
578
  {
579
    return IsNull()
580
           ? aOther.IsNull()
581
           : !aOther.IsNull() && mValue == aOther.mValue;
582
  }
583
  bool operator!=(const TimeStamp& aOther) const
584
  {
585
    return !(*this == aOther);
586
  }
587
588
  // Comparing TimeStamps for equality should be discouraged. Adding
589
  // two TimeStamps, or scaling TimeStamps, is nonsense and must never
590
  // be allowed.
591
592
  static MFBT_API void Startup();
593
  static MFBT_API void Shutdown();
594
595
private:
596
  friend struct IPC::ParamTraits<mozilla::TimeStamp>;
597
598
8.18k
  MOZ_IMPLICIT TimeStamp(TimeStampValue aValue) : mValue(aValue) {}
599
600
  static MFBT_API TimeStamp Now(bool aHighResolution);
601
602
  /**
603
   * Computes the uptime of the current process in microseconds. The result
604
   * is platform-dependent and needs to be checked against existing timestamps
605
   * for consistency.
606
   *
607
   * @returns The number of microseconds since the calling process was started
608
   *          or 0 if an error was encountered while computing the uptime
609
   */
610
  static MFBT_API uint64_t ComputeProcessUptime();
611
612
  /**
613
   * When built with PRIntervalTime, a value of 0 means this instance
614
   * is "null". Otherwise, the low 32 bits represent a PRIntervalTime,
615
   * and the high 32 bits represent a counter of the number of
616
   * rollovers of PRIntervalTime that we've seen. This counter starts
617
   * at 1 to avoid a real time colliding with the "null" value.
618
   *
619
   * PR_INTERVAL_MAX is set at 100,000 ticks per second. So the minimum
620
   * time to wrap around is about 2^64/100000 seconds, i.e. about
621
   * 5,849,424 years.
622
   *
623
   * When using a system clock, a value is system dependent.
624
   */
625
  TimeStampValue mValue;
626
};
627
628
} // namespace mozilla
629
630
#endif /* mozilla_TimeStamp_h */