Bug 1432429 TimeStamp::NowFuzzy 3/14 draft
authorAndrea Marchesini <amarchesini@mozilla.com>
Fri, 15 Jun 2018 19:09:00 -0700
changeset 826364 abe057d6ca2db613e85af69a1eb98ca28b1e8ec1
parent 826363 950d2f33c1aa53ab08ae0b4cbcfc34a385ba0207
child 826365 a184f88143f7c23a42e6041e076d368d96881f1c
push id118310
push userbmo:tom@mozilla.com
push dateFri, 03 Aug 2018 18:22:17 +0000
bugs1432429
milestone62.0a1
Bug 1432429 TimeStamp::NowFuzzy 3/14 MozReview-Commit-ID: 4zzycUxn0jX
mozglue/misc/TimeStamp.cpp
mozglue/misc/TimeStamp.h
mozglue/misc/TimeStamp_darwin.cpp
mozglue/misc/TimeStamp_posix.cpp
mozglue/misc/TimeStamp_windows.cpp
mozglue/misc/TimeStamp_windows.h
--- a/mozglue/misc/TimeStamp.cpp
+++ b/mozglue/misc/TimeStamp.cpp
@@ -7,16 +7,20 @@
 /*
  * Implementation of the OS-independent methods of the TimeStamp class
  */
 
 #include "mozilla/TimeStamp.h"
 #include <stdio.h>
 #include <string.h>
 
+#ifdef MOZ_FUZZYFOX
+#include "mozilla/Atomics.h"
+#endif
+
 namespace mozilla {
 
 /**
  * Wrapper class used to initialize static data used by the TimeStamp class
  */
 struct TimeStampInitialization
 {
   /**
@@ -39,16 +43,26 @@ struct TimeStampInitialization
   };
 
   ~TimeStampInitialization()
   {
     TimeStamp::Shutdown();
   };
 };
 
+#ifdef MOZ_FUZZYFOX
+#ifdef XP_WIN
+static Atomic<uint64_t> sCanonicalGTC;
+static Atomic<uint64_t> sCanonicalQPC;
+static Atomic<bool> sCanonicalHasQPC;
+#else
+static Atomic<uint64_t> sCanonicalNow;
+#endif
+#endif
+
 static TimeStampInitialization sInitOnce;
 
 MFBT_API TimeStamp
 TimeStamp::ProcessCreation(bool* aIsInconsistent)
 {
   if (aIsInconsistent) {
     *aIsInconsistent = false;
   }
@@ -88,9 +102,38 @@ TimeStamp::ProcessCreation(bool* aIsInco
 }
 
 void
 TimeStamp::RecordProcessRestart()
 {
   sInitOnce.mProcessCreation = TimeStamp();
 }
 
+#ifdef MOZ_FUZZYFOX
+MFBT_API TimeStamp
+TimeStamp::NowFuzzy(TimeStampValue aValue)
+{
+#ifdef XP_WIN
+  TimeStampValue canonicalNow = TimeStampValue(sCanonicalGTC, sCanonicalQPC, sCanonicalHasQPC);
+#else
+  TimeStampValue canonicalNow = sCanonicalNow;
+#endif
+  if(canonicalNow > 0) {
+    return TimeStamp(canonicalNow, true);
+  }
+
+  return TimeStamp(aValue);
+}
+
+MFBT_API void
+TimeStamp::UpdateFuzzyTimeStamp(TimeStamp aValue)
+{
+  #ifdef XP_WIN
+  sCanonicalGTC = aValue.mValue.mGTC;
+  sCanonicalQPC = aValue.mValue.mQPC;
+  sCanonicalHasQPC = aValue.mValue.mHasQPC;
+  #else
+  sCanonicalNow = aValue;
+  #endif
+}
+#endif
+
 } // namespace mozilla
--- a/mozglue/misc/TimeStamp.h
+++ b/mozglue/misc/TimeStamp.h
@@ -408,17 +408,22 @@ typedef BaseTimeDuration<TimeDurationVal
  * unless there is a specific reason not to do so.
  */
 class TimeStamp
 {
 public:
   /**
    * Initialize to the "null" moment
    */
-  constexpr TimeStamp() : mValue(0) {}
+  constexpr TimeStamp()
+    : mValue(0)
+#ifdef MOZ_FUZZYFOX
+    , mUsedCanonicalNow(false)
+#endif
+  {}
   // Default copy-constructor and assignment are OK
 
   /**
    * The system timestamps are the same as the TimeStamp
    * retrieved by mozilla::TimeStamp. Since we need this for
    * vsync timestamps, we enable the creation of mozilla::TimeStamps
    * on platforms that support vsync aligned refresh drivers / compositors
    * Verified true as of Jan 31, 2015: B2G and OS X
@@ -463,16 +468,23 @@ public:
    * NowLoRes() has been introduced to workaround performance problems of
    * QueryPerformanceCounter on the Windows platform.  NowLoRes() is giving
    * lower precision, usually 15.6 ms, but with very good performance benefit.
    * Use it for measurements of longer times, like >200ms timeouts.
    */
   static TimeStamp Now() { return Now(true); }
   static TimeStamp NowLoRes() { return Now(false); }
 
+#ifdef MOZ_FUZZYFOX
+  static TimeStamp NowReally() { return NowReally(true); }
+
+  static MFBT_API TimeStamp NowFuzzy(TimeStampValue aValue);
+  static MFBT_API void UpdateFuzzyTimeStamp(TimeStamp aValue);
+#endif
+
   /**
    * Return a timestamp representing the time when the current process was
    * created which will be comparable with other timestamps taken with this
    * class. If the actual process creation time is detected to be inconsistent
    * the @a aIsInconsistent parameter will be set to true, the returned
    * timestamp however will still be valid though inaccurate.
    *
    * @param aIsInconsistent If non-null, set to true if an inconsistency was
@@ -590,20 +602,36 @@ public:
   // be allowed.
 
   static MFBT_API void Startup();
   static MFBT_API void Shutdown();
 
 private:
   friend struct IPC::ParamTraits<mozilla::TimeStamp>;
 
-  MOZ_IMPLICIT TimeStamp(TimeStampValue aValue) : mValue(aValue) {}
+  MOZ_IMPLICIT TimeStamp(TimeStampValue aValue)
+    : mValue(aValue)
+#ifdef MOZ_FUZZYFOX
+    , mUsedCanonicalNow(false)
+#endif
+  {}
+
+#ifdef MOZ_FUZZYFOX
+  MOZ_IMPLICIT TimeStamp(TimeStampValue aValue, bool aUsedCanonicalNow)
+    : mValue(aValue)
+    , mUsedCanonicalNow(aUsedCanonicalNow)
+  {}
+#endif
 
   static MFBT_API TimeStamp Now(bool aHighResolution);
 
+#ifdef MOZ_FUZZYFOX
+  static MFBT_API TimeStamp NowReally(bool aHighResolution);
+#endif
+
   /**
    * Computes the uptime of the current process in microseconds. The result
    * is platform-dependent and needs to be checked against existing timestamps
    * for consistency.
    *
    * @returns The number of microseconds since the calling process was started
    *          or 0 if an error was encountered while computing the uptime
    */
@@ -618,13 +646,18 @@ private:
    *
    * PR_INTERVAL_MAX is set at 100,000 ticks per second. So the minimum
    * time to wrap around is about 2^64/100000 seconds, i.e. about
    * 5,849,424 years.
    *
    * When using a system clock, a value is system dependent.
    */
   TimeStampValue mValue;
+
+#ifdef MOZ_FUZZYFOX
+  bool mUsedCanonicalNow;
+  friend class Fuzzyfox;
+#endif
 };
 
 } // namespace mozilla
 
 #endif /* mozilla_TimeStamp_h */
--- a/mozglue/misc/TimeStamp_darwin.cpp
+++ b/mozglue/misc/TimeStamp_darwin.cpp
@@ -154,18 +154,30 @@ TimeStamp::Startup()
 void
 TimeStamp::Shutdown()
 {
 }
 
 TimeStamp
 TimeStamp::Now(bool aHighResolution)
 {
+#ifdef MOZ_FUZZYFOX
+  return TimeStamp::NowFuzzy(ClockTime());
+#else
+  return TimeStamp(ClockTime());
+#endif
+}
+
+#ifdef MOZ_FUZZYFOX
+TimeStamp
+TimeStamp::NowReally(bool aHighResolution)
+{
   return TimeStamp(ClockTime());
 }
+#endif
 
 // Computes and returns the process uptime in microseconds.
 // Returns 0 if an error was encountered.
 
 uint64_t
 TimeStamp::ComputeProcessUptime()
 {
   struct timeval tv;
--- a/mozglue/misc/TimeStamp_posix.cpp
+++ b/mozglue/misc/TimeStamp_posix.cpp
@@ -197,18 +197,30 @@ TimeStamp::Startup()
 void
 TimeStamp::Shutdown()
 {
 }
 
 TimeStamp
 TimeStamp::Now(bool aHighResolution)
 {
+#ifdef MOZ_FUZZYFOX
+  return TimeStamp::NowFuzzy(ClockTimeNs());
+#else
+  return TimeStamp(ClockTimeNs());
+#endif
+}
+
+#ifdef MOZ_FUZZYFOX
+TimeStamp
+TimeStamp::NowReally(bool aHighResolution)
+{
   return TimeStamp(ClockTimeNs());
 }
+#endif
 
 #if defined(XP_LINUX) || defined(ANDROID)
 
 // Calculates the amount of jiffies that have elapsed since boot and up to the
 // starttime value of a specific process as found in its /proc/*/stat file.
 // Returns 0 if an error occurred.
 
 static uint64_t
--- a/mozglue/misc/TimeStamp_windows.cpp
+++ b/mozglue/misc/TimeStamp_windows.cpp
@@ -518,18 +518,36 @@ MFBT_API TimeStamp
 TimeStamp::Now(bool aHighResolution)
 {
   // sUseQPC is volatile
   bool useQPC = (aHighResolution && sUseQPC);
 
   // Both values are in [mt] units.
   ULONGLONG QPC = useQPC ? PerformanceCounter() : uint64_t(0);
   ULONGLONG GTC = ms2mt(GetTickCount64());
+#ifdef MOZ_FUZZYFOX
+  return TimeStamp::NowFuzzy(TimeStampValue(GTC, QPC, useQPC));
+#else
+  return TimeStamp(TimeStampValue(GTC, QPC, useQPC));
+#endif
+}
+
+#ifdef MOZ_FUZZYFOX
+MFBT_API TimeStamp
+TimeStamp::NowReally(bool aHighResolution)
+{
+  // sUseQPC is volatile
+  bool useQPC = (aHighResolution && sUseQPC);
+
+  // Both values are in [mt] units.
+  ULONGLONG QPC = useQPC ? PerformanceCounter() : uint64_t(0);
+  ULONGLONG GTC = ms2mt(GetTickCount64());
   return TimeStamp(TimeStampValue(GTC, QPC, useQPC));
 }
+#endif
 
 // Computes and returns the process uptime in microseconds.
 // Returns 0 if an error was encountered.
 
 MFBT_API uint64_t
 TimeStamp::ComputeProcessUptime()
 {
   SYSTEMTIME nowSys;
--- a/mozglue/misc/TimeStamp_windows.h
+++ b/mozglue/misc/TimeStamp_windows.h
@@ -30,16 +30,17 @@ MFBT_API uint64_t
 GetQueryPerformanceFrequencyPerSec();
 
 class TimeStamp;
 
 class TimeStampValue
 {
   friend struct IPC::ParamTraits<mozilla::TimeStampValue>;
   friend class TimeStamp;
+  friend class Fuzzyfox;
 
   // Both QPC and GTC are kept in [mt] units.
   uint64_t mGTC;
   uint64_t mQPC;
   bool mHasQPC;
   bool mIsNull;
 
   MFBT_API TimeStampValue(uint64_t aGTC, uint64_t aQPC, bool aHasQPC);