LCOV - code coverage report
Current view: top level - mozglue/misc - TimeStamp.h (source / functions) Hit Total Coverage
Test: output.info Lines: 132 158 83.5 %
Date: 2017-07-14 16:53:18 Functions: 67 78 85.9 %
Legend: Lines: hit not hit

          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 */

Generated by: LCOV version 1.13