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 : #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 3177 : constexpr BaseTimeDuration() : mValue(0) {}
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 313 : MOZ_IMPLICIT BaseTimeDuration(_SomethingVeryRandomHere* aZero) : mValue(0)
72 : {
73 313 : MOZ_ASSERT(!aZero, "Who's playing funny games here?");
74 313 : }
75 : // Default copy-constructor and assignment are OK
76 :
77 : // Converting copy-constructor and assignment operator
78 : template <typename E>
79 1054 : explicit BaseTimeDuration(const BaseTimeDuration<E>& aOther)
80 1054 : : mValue(aOther.mValue)
81 1054 : { }
82 :
83 : template <typename E>
84 156 : BaseTimeDuration& operator=(const BaseTimeDuration<E>& aOther)
85 : {
86 156 : mValue = aOther.mValue;
87 156 : return *this;
88 : }
89 :
90 8269 : double ToSeconds() const
91 : {
92 8269 : if (mValue == INT64_MAX) {
93 0 : return PositiveInfinity<double>();
94 : }
95 8269 : if (mValue == INT64_MIN) {
96 0 : return NegativeInfinity<double>();
97 : }
98 8269 : return BaseTimeDurationPlatformUtils::ToSeconds(mValue);
99 : }
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 0 : double ToSecondsSigDigits() const
104 : {
105 0 : if (mValue == INT64_MAX) {
106 0 : return PositiveInfinity<double>();
107 : }
108 0 : if (mValue == INT64_MIN) {
109 0 : return NegativeInfinity<double>();
110 : }
111 0 : return BaseTimeDurationPlatformUtils::ToSecondsSigDigits(mValue);
112 : }
113 7859 : double ToMilliseconds() const { return ToSeconds() * 1000.0; }
114 564 : 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 388 : static inline BaseTimeDuration FromSeconds(double aSeconds)
122 : {
123 388 : return FromMilliseconds(aSeconds * 1000.0);
124 : }
125 1639 : static BaseTimeDuration FromMilliseconds(double aMilliseconds)
126 : {
127 1639 : if (aMilliseconds == PositiveInfinity<double>()) {
128 0 : return Forever();
129 : }
130 1639 : if (aMilliseconds == NegativeInfinity<double>()) {
131 0 : return FromTicks(INT64_MIN);
132 : }
133 1639 : return FromTicks(
134 1639 : BaseTimeDurationPlatformUtils::TicksFromMilliseconds(aMilliseconds));
135 : }
136 7 : static inline BaseTimeDuration FromMicroseconds(double aMicroseconds)
137 : {
138 7 : return FromMilliseconds(aMicroseconds / 1000.0);
139 : }
140 :
141 755 : static BaseTimeDuration Forever()
142 : {
143 755 : return FromTicks(INT64_MAX);
144 : }
145 :
146 826 : BaseTimeDuration operator+(const BaseTimeDuration& aOther) const
147 : {
148 826 : return FromTicks(ValueCalculator::Add(mValue, aOther.mValue));
149 : }
150 389 : BaseTimeDuration operator-(const BaseTimeDuration& aOther) const
151 : {
152 389 : return FromTicks(ValueCalculator::Subtract(mValue, aOther.mValue));
153 : }
154 802 : BaseTimeDuration& operator+=(const BaseTimeDuration& aOther)
155 : {
156 802 : mValue = ValueCalculator::Add(mValue, aOther.mValue);
157 802 : return *this;
158 : }
159 84 : BaseTimeDuration& operator-=(const BaseTimeDuration& aOther)
160 : {
161 84 : mValue = ValueCalculator::Subtract(mValue, aOther.mValue);
162 84 : return *this;
163 : }
164 24 : BaseTimeDuration operator-() const
165 : {
166 : // We don't just use FromTicks(ValueCalculator::Subtract(0, mValue))
167 : // since that won't give the correct result for -TimeDuration::Forever().
168 : int64_t ticks;
169 24 : if (mValue == INT64_MAX) {
170 0 : ticks = INT64_MIN;
171 24 : } else if (mValue == INT64_MIN) {
172 0 : ticks = INT64_MAX;
173 : } else {
174 24 : ticks = -mValue;
175 : }
176 :
177 24 : return FromTicks(ticks);
178 : }
179 :
180 18 : static BaseTimeDuration Max(const BaseTimeDuration& aA,
181 : const BaseTimeDuration& aB)
182 : {
183 18 : return FromTicks(std::max(aA.mValue, aB.mValue));
184 : }
185 8 : static BaseTimeDuration Min(const BaseTimeDuration& aA,
186 : const BaseTimeDuration& aB)
187 : {
188 8 : return FromTicks(std::min(aA.mValue, aB.mValue));
189 : }
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 580 : BaseTimeDuration MultDouble(double aMultiplier) const
203 : {
204 580 : return FromTicks(ValueCalculator::Multiply(mValue, aMultiplier));
205 : }
206 0 : BaseTimeDuration operator*(const int32_t aMultiplier) const
207 : {
208 0 : return FromTicks(ValueCalculator::Multiply(mValue, aMultiplier));
209 : }
210 41 : BaseTimeDuration operator*(const uint32_t aMultiplier) const
211 : {
212 41 : return FromTicks(ValueCalculator::Multiply(mValue, aMultiplier));
213 : }
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 : {
227 : MOZ_ASSERT(aDivisor != 0, "Division by zero");
228 : return FromTicks(ValueCalculator::Divide(mValue, aDivisor));
229 : }
230 156 : double operator/(const BaseTimeDuration& aOther) const
231 : {
232 : #ifndef MOZ_B2G
233 : // Bug 1066388 - This fails on B2G ICS Emulator
234 156 : MOZ_ASSERT(aOther.mValue != 0, "Division by zero");
235 : #endif
236 156 : return ValueCalculator::DivideDouble(mValue, aOther.mValue);
237 : }
238 : BaseTimeDuration operator%(const BaseTimeDuration& aOther) const
239 : {
240 : MOZ_ASSERT(aOther.mValue != 0, "Division by zero");
241 : return FromTicks(ValueCalculator::Modulo(mValue, aOther.mValue));
242 : }
243 :
244 : template<typename E>
245 2937 : bool operator<(const BaseTimeDuration<E>& aOther) const
246 : {
247 2937 : return mValue < aOther.mValue;
248 : }
249 : template<typename E>
250 0 : bool operator<=(const BaseTimeDuration<E>& aOther) const
251 : {
252 0 : return mValue <= aOther.mValue;
253 : }
254 : template<typename E>
255 248 : bool operator>=(const BaseTimeDuration<E>& aOther) const
256 : {
257 248 : return mValue >= aOther.mValue;
258 : }
259 : template<typename E>
260 239 : bool operator>(const BaseTimeDuration<E>& aOther) const
261 : {
262 239 : return mValue > aOther.mValue;
263 : }
264 : template<typename E>
265 2099 : bool operator==(const BaseTimeDuration<E>& aOther) const
266 : {
267 2099 : return mValue == aOther.mValue;
268 : }
269 : template<typename E>
270 260 : bool operator!=(const BaseTimeDuration<E>& aOther) const
271 : {
272 260 : return mValue != aOther.mValue;
273 : }
274 47 : bool IsZero() const
275 : {
276 47 : return mValue == 0;
277 : }
278 0 : explicit operator bool() const
279 : {
280 0 : return mValue != 0;
281 : }
282 :
283 : friend std::ostream& operator<<(std::ostream& aStream,
284 : const BaseTimeDuration& aDuration) {
285 : return aStream << aDuration.ToMilliseconds() << " ms";
286 : }
287 :
288 : // Return a best guess at the system's current timing resolution,
289 : // which might be variable. BaseTimeDurations below this order of
290 : // magnitude are meaningless, and those at the same order of
291 : // magnitude or just above are suspect.
292 0 : static BaseTimeDuration Resolution() {
293 0 : return FromTicks(BaseTimeDurationPlatformUtils::ResolutionInTicks());
294 : }
295 :
296 : // We could define additional operators here:
297 : // -- convert to/from other time units
298 : // -- scale duration by a float
299 : // but let's do that on demand.
300 : // Comparing durations for equality will only lead to bugs on
301 : // platforms with high-resolution timers.
302 :
303 : private:
304 : friend class TimeStamp;
305 : friend struct IPC::ParamTraits<mozilla::BaseTimeDuration<ValueCalculator>>;
306 : template <typename>
307 : friend class BaseTimeDuration;
308 :
309 13185 : static BaseTimeDuration FromTicks(int64_t aTicks)
310 : {
311 13185 : BaseTimeDuration t;
312 13185 : t.mValue = aTicks;
313 13185 : return t;
314 : }
315 :
316 : static BaseTimeDuration FromTicks(double aTicks)
317 : {
318 : // NOTE: this MUST be a >= test, because int64_t(double(INT64_MAX))
319 : // overflows and gives INT64_MIN.
320 : if (aTicks >= double(INT64_MAX)) {
321 : return FromTicks(INT64_MAX);
322 : }
323 :
324 : // This MUST be a <= test.
325 : if (aTicks <= double(INT64_MIN)) {
326 : return FromTicks(INT64_MIN);
327 : }
328 :
329 : return FromTicks(int64_t(aTicks));
330 : }
331 :
332 : // Duration, result is implementation-specific difference of two TimeStamps
333 : int64_t mValue;
334 : };
335 :
336 : /**
337 : * Perform arithmetic operations on the value of a BaseTimeDuration without
338 : * doing strict checks on the range of values.
339 : */
340 : class TimeDurationValueCalculator
341 : {
342 : public:
343 838 : static int64_t Add(int64_t aA, int64_t aB) { return aA + aB; }
344 449 : static int64_t Subtract(int64_t aA, int64_t aB) { return aA - aB; }
345 :
346 : template <typename T>
347 41 : static int64_t Multiply(int64_t aA, T aB)
348 : {
349 : static_assert(IsIntegral<T>::value,
350 : "Using integer multiplication routine with non-integer type."
351 : " Further specialization required");
352 41 : return aA * static_cast<int64_t>(aB);
353 : }
354 :
355 : static int64_t Divide(int64_t aA, int64_t aB) { return aA / aB; }
356 0 : static double DivideDouble(int64_t aA, int64_t aB)
357 : {
358 0 : return static_cast<double>(aA) / aB;
359 : }
360 : static int64_t Modulo(int64_t aA, int64_t aB) { return aA % aB; }
361 : };
362 :
363 : template <>
364 : inline int64_t
365 106 : TimeDurationValueCalculator::Multiply<double>(int64_t aA, double aB)
366 : {
367 106 : return static_cast<int64_t>(aA * aB);
368 : }
369 :
370 : /**
371 : * Specialization of BaseTimeDuration that uses TimeDurationValueCalculator for
372 : * arithmetic on the mValue member.
373 : *
374 : * Use this class for time durations that are *not* expected to hold values of
375 : * Forever (or the negative equivalent) or when such time duration are *not*
376 : * expected to be used in arithmetic operations.
377 : */
378 : typedef BaseTimeDuration<TimeDurationValueCalculator> TimeDuration;
379 :
380 : /**
381 : * Instances of this class represent moments in time, or a special
382 : * "null" moment. We do not use the non-monotonic system clock or
383 : * local time, since they can be reset, causing apparent backward
384 : * travel in time, which can confuse algorithms. Instead we measure
385 : * elapsed time according to the system. This time can never go
386 : * backwards (i.e. it never wraps around, at least not in less than
387 : * five million years of system elapsed time). It might not advance
388 : * while the system is sleeping. If TimeStamp::SetNow() is not called
389 : * at all for hours or days, we might not notice the passage of some
390 : * of that time.
391 : *
392 : * We deliberately do not expose a way to convert TimeStamps to some
393 : * particular unit. All you can do is compute a difference between two
394 : * TimeStamps to get a TimeDuration. You can also add a TimeDuration
395 : * to a TimeStamp to get a new TimeStamp. You can't do something
396 : * meaningless like add two TimeStamps.
397 : *
398 : * Internally this is implemented as either a wrapper around
399 : * - high-resolution, monotonic, system clocks if they exist on this
400 : * platform
401 : * - PRIntervalTime otherwise. We detect wraparounds of
402 : * PRIntervalTime and work around them.
403 : *
404 : * This class is similar to C++11's time_point, however it is
405 : * explicitly nullable and provides an IsNull() method. time_point
406 : * is initialized to the clock's epoch and provides a
407 : * time_since_epoch() method that functions similiarly. i.e.
408 : * t.IsNull() is equivalent to t.time_since_epoch() == decltype(t)::duration::zero();
409 : */
410 : class TimeStamp
411 : {
412 : public:
413 : /**
414 : * Initialize to the "null" moment
415 : */
416 18700 : 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 : * UNTESTED ON OTHER PLATFORMS
429 : */
430 : #if defined(MOZ_WIDGET_GONK) || defined(XP_DARWIN) || \
431 : defined(MOZ_WIDGET_ANDROID)
432 : static TimeStamp FromSystemTime(int64_t aSystemTime)
433 : {
434 : static_assert(sizeof(aSystemTime) == sizeof(TimeStampValue),
435 : "System timestamp should be same units as TimeStampValue");
436 : return TimeStamp(aSystemTime);
437 : }
438 : #endif
439 :
440 : /**
441 : * Return true if this is the "null" moment
442 : */
443 37310 : bool IsNull() const { return mValue == 0; }
444 :
445 : /**
446 : * Return true if this is not the "null" moment, may be used in tests, e.g.:
447 : * |if (timestamp) { ... }|
448 : */
449 2962 : explicit operator bool() const
450 : {
451 2962 : return mValue != 0;
452 : }
453 :
454 : /**
455 : * Return a timestamp reflecting the current elapsed system time. This
456 : * is monotonically increasing (i.e., does not decrease) over the
457 : * lifetime of this process' XPCOM session.
458 : *
459 : * Now() is trying to ensure the best possible precision on each platform,
460 : * at least one millisecond.
461 : *
462 : * NowLoRes() has been introduced to workaround performance problems of
463 : * QueryPerformanceCounter on the Windows platform. NowLoRes() is giving
464 : * lower precision, usually 15.6 ms, but with very good performance benefit.
465 : * Use it for measurements of longer times, like >200ms timeouts.
466 : */
467 18728 : static TimeStamp Now() { return Now(true); }
468 2661 : static TimeStamp NowLoRes() { return Now(false); }
469 :
470 : /**
471 : * Return a timestamp representing the time when the current process was
472 : * created which will be comparable with other timestamps taken with this
473 : * class. If the actual process creation time is detected to be inconsistent
474 : * the @a aIsInconsistent parameter will be set to true, the returned
475 : * timestamp however will still be valid though inaccurate.
476 : *
477 : * @param aIsInconsistent If non-null, set to true if an inconsistency was
478 : * detected in the process creation time
479 : * @returns A timestamp representing the time when the process was created,
480 : * this timestamp is always valid even when errors are reported
481 : */
482 : static MFBT_API TimeStamp ProcessCreation(bool* aIsInconsistent = nullptr);
483 :
484 : /**
485 : * Records a process restart. After this call ProcessCreation() will return
486 : * the time when the browser was restarted instead of the actual time when
487 : * the process was created.
488 : */
489 : static MFBT_API void RecordProcessRestart();
490 :
491 : /**
492 : * Compute the difference between two timestamps. Both must be non-null.
493 : */
494 8907 : TimeDuration operator-(const TimeStamp& aOther) const
495 : {
496 8907 : MOZ_ASSERT(!IsNull(), "Cannot compute with a null value");
497 8907 : MOZ_ASSERT(!aOther.IsNull(), "Cannot compute with aOther null value");
498 : static_assert(-INT64_MAX > INT64_MIN, "int64_t sanity check");
499 8907 : int64_t ticks = int64_t(mValue - aOther.mValue);
500 : // Check for overflow.
501 8907 : if (mValue > aOther.mValue) {
502 8880 : if (ticks < 0) {
503 0 : ticks = INT64_MAX;
504 : }
505 : } else {
506 27 : if (ticks > 0) {
507 0 : ticks = INT64_MIN;
508 : }
509 : }
510 8907 : return TimeDuration::FromTicks(ticks);
511 : }
512 :
513 1254 : TimeStamp operator+(const TimeDuration& aOther) const
514 : {
515 1254 : TimeStamp result = *this;
516 1254 : result += aOther;
517 1254 : return result;
518 : }
519 199 : TimeStamp operator-(const TimeDuration& aOther) const
520 : {
521 199 : TimeStamp result = *this;
522 199 : result -= aOther;
523 199 : return result;
524 : }
525 1285 : TimeStamp& operator+=(const TimeDuration& aOther)
526 : {
527 1285 : MOZ_ASSERT(!IsNull(), "Cannot compute with a null value");
528 1285 : TimeStampValue value = mValue + aOther.mValue;
529 : // Check for underflow.
530 : // (We don't check for overflow because it's not obvious what the error
531 : // behavior should be in that case.)
532 1285 : if (aOther.mValue < 0 && value > mValue) {
533 0 : value = 0;
534 : }
535 1285 : mValue = value;
536 1285 : return *this;
537 : }
538 199 : TimeStamp& operator-=(const TimeDuration& aOther)
539 : {
540 199 : MOZ_ASSERT(!IsNull(), "Cannot compute with a null value");
541 199 : TimeStampValue value = mValue - aOther.mValue;
542 : // Check for underflow.
543 : // (We don't check for overflow because it's not obvious what the error
544 : // behavior should be in that case.)
545 199 : if (aOther.mValue > 0 && value > mValue) {
546 0 : value = 0;
547 : }
548 199 : mValue = value;
549 199 : return *this;
550 : }
551 :
552 4114 : bool operator<(const TimeStamp& aOther) const
553 : {
554 4114 : MOZ_ASSERT(!IsNull(), "Cannot compute with a null value");
555 4114 : MOZ_ASSERT(!aOther.IsNull(), "Cannot compute with aOther null value");
556 4114 : return mValue < aOther.mValue;
557 : }
558 244 : bool operator<=(const TimeStamp& aOther) const
559 : {
560 244 : MOZ_ASSERT(!IsNull(), "Cannot compute with a null value");
561 244 : MOZ_ASSERT(!aOther.IsNull(), "Cannot compute with aOther null value");
562 244 : return mValue <= aOther.mValue;
563 : }
564 819 : bool operator>=(const TimeStamp& aOther) const
565 : {
566 819 : MOZ_ASSERT(!IsNull(), "Cannot compute with a null value");
567 819 : MOZ_ASSERT(!aOther.IsNull(), "Cannot compute with aOther null value");
568 819 : return mValue >= aOther.mValue;
569 : }
570 829 : bool operator>(const TimeStamp& aOther) const
571 : {
572 829 : MOZ_ASSERT(!IsNull(), "Cannot compute with a null value");
573 829 : MOZ_ASSERT(!aOther.IsNull(), "Cannot compute with aOther null value");
574 829 : return mValue > aOther.mValue;
575 : }
576 492 : bool operator==(const TimeStamp& aOther) const
577 : {
578 492 : return IsNull()
579 929 : ? aOther.IsNull()
580 929 : : !aOther.IsNull() && mValue == aOther.mValue;
581 : }
582 168 : bool operator!=(const TimeStamp& aOther) const
583 : {
584 168 : return !(*this == aOther);
585 : }
586 :
587 : // Comparing TimeStamps for equality should be discouraged. Adding
588 : // two TimeStamps, or scaling TimeStamps, is nonsense and must never
589 : // be allowed.
590 :
591 : static MFBT_API void Startup();
592 : static MFBT_API void Shutdown();
593 :
594 : private:
595 : friend struct IPC::ParamTraits<mozilla::TimeStamp>;
596 : friend void StartupTimelineRecordExternal(int, uint64_t);
597 :
598 21392 : 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 */
|