Bug 803039 - Use TimeStamp instead of PRTime to store the idle time. r=jlebar
authorShelly Lin <slin@mozilla.com>
Fri, 26 Oct 2012 10:17:36 +0800
changeset 115144 4998bde6d220408a28a65e767ef0f68939afa9e1
parent 115143 5a1ff68f37d983f75e9b213fca17fd78d55fc7d8
child 115145 f3ef58ba9e55d4ce808150ea8d469861c3067cf0
push id23973
push useremorley@mozilla.com
push dateThu, 06 Dec 2012 10:04:18 +0000
treeherdermozilla-central@ddda5400c826 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjlebar
bugs803039
milestone20.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 803039 - Use TimeStamp instead of PRTime to store the idle time. r=jlebar
widget/xpwidgets/nsIdleService.cpp
widget/xpwidgets/nsIdleService.h
--- a/widget/xpwidgets/nsIdleService.cpp
+++ b/widget/xpwidgets/nsIdleService.cpp
@@ -376,20 +376,20 @@ nsIdleService* gIdleService;
 
 already_AddRefed<nsIdleService>
 nsIdleService::GetInstance()
 {
   nsRefPtr<nsIdleService> instance(gIdleService);
   return instance.forget();
 }
 
-nsIdleService::nsIdleService() : mCurrentlySetToTimeoutAtInPR(0),
+nsIdleService::nsIdleService() : mCurrentlySetToTimeoutAt(TimeStamp()),
                                  mAnyObserverIdle(false),
                                  mDeltaToNextIdleSwitchInS(UINT32_MAX),
-                                 mLastUserInteractionInPR(PR_Now())
+                                 mLastUserInteraction(TimeStamp::Now())
 {
 #ifdef PR_LOGGING
   if (sLog == NULL)
     sLog = PR_NewLogModule("idleService");
 #endif
   MOZ_ASSERT(!gIdleService);
   gIdleService = this;
   mDailyIdle = new nsIdleServiceDaily(this);
@@ -502,17 +502,18 @@ nsIdleService::RemoveIdleObserver(nsIObs
 NS_IMETHODIMP
 nsIdleService::ResetIdleTimeOut(uint32_t idleDeltaInMS)
 {
   PR_LOG(sLog, PR_LOG_DEBUG,
          ("idleService: Reset idle timeout (last interaction %u msec)",
           idleDeltaInMS));
 
   // Store the time
-  mLastUserInteractionInPR = PR_Now() - (idleDeltaInMS * PR_USEC_PER_MSEC);
+  mLastUserInteraction = TimeStamp::Now() -
+                         TimeDuration::FromMilliseconds(idleDeltaInMS);
 
   // If no one is idle, then we are done, any existing timers can keep running.
   if (!mAnyObserverIdle) {
     PR_LOG(sLog, PR_LOG_DEBUG,
            ("idleService: Reset idle timeout: no idle observers"));
     return NS_OK;
   }
 
@@ -589,18 +590,18 @@ nsIdleService::GetIdleTime(uint32_t* idl
 
   bool polledIdleTimeIsValid = PollIdleTime(&polledIdleTimeMS);
 
   PR_LOG(sLog, PR_LOG_DEBUG,
          ("idleService: Get idle time: polled %u msec, valid = %d",
           polledIdleTimeMS, polledIdleTimeIsValid));
   
   // timeSinceReset is in milliseconds.
-  uint32_t timeSinceResetInMS = (PR_Now() - mLastUserInteractionInPR) /
-                                PR_USEC_PER_MSEC;
+  TimeDuration timeSinceReset = TimeStamp::Now() - mLastUserInteraction;
+  uint32_t timeSinceResetInMS = timeSinceReset.ToMilliseconds();
 
   PR_LOG(sLog, PR_LOG_DEBUG,
          ("idleService: Get idle time: time since reset %u msec",
           timeSinceResetInMS));
 #ifdef ANDROID
   __android_log_print(ANDROID_LOG_INFO, "IdleService",
                       "Get idle time: time since reset %u msec",
                       timeSinceResetInMS);
@@ -639,17 +640,17 @@ nsIdleService::StaticIdleTimerCallback(n
 {
   static_cast<nsIdleService*>(aClosure)->IdleTimerCallback();
 }
 
 void
 nsIdleService::IdleTimerCallback(void)
 {
   // Remember that we no longer have a timer running.
-  mCurrentlySetToTimeoutAtInPR = 0;
+  mCurrentlySetToTimeoutAt = TimeStamp();
 
   // Get the current idle time.
   uint32_t currentIdleTimeInMS;
 
   if (NS_FAILED(GetIdleTime(&currentIdleTimeInMS))) {
     PR_LOG(sLog, PR_LOG_ALWAYS,
            ("idleService: Idle timer callback: failed to get idle time"));
 #ifdef ANDROID
@@ -667,18 +668,18 @@ nsIdleService::IdleTimerCallback(void)
                       "Idle timer callback: current idle time %u msec",
                       currentIdleTimeInMS);
 #endif
 
   // Check if we have had some user interaction we didn't handle previously
   // we do the calculation in ms to lessen the chance for rounding errors to
   // trigger wrong results, it is also very important that we call PR_Now AFTER
   // the call to GetIdleTime().
-  if (((PR_Now() - mLastUserInteractionInPR) / PR_USEC_PER_MSEC) >
-      currentIdleTimeInMS)
+  TimeDuration aIdleTime = TimeStamp::Now() - mLastUserInteraction;
+  if (aIdleTime.ToMilliseconds() > currentIdleTimeInMS)
   {
     // We had user activity, so handle that part first (to ensure the listeners
     // don't risk getting an non-idle after they get a new idle indication.
     ResetIdleTimeOut(currentIdleTimeInMS);
 
     // NOTE: We can't bail here, as we might have something already timed out.
   }
 
@@ -754,69 +755,66 @@ nsIdleService::IdleTimerCallback(void)
 #endif
     notifyList[numberOfPendingNotifications]->Observe(this,
                                                       OBSERVER_TOPIC_IDLE,
                                                       timeStr.get());
   }
 }
 
 void
-nsIdleService::SetTimerExpiryIfBefore(PRTime aNextTimeoutInPR)
+nsIdleService::SetTimerExpiryIfBefore(TimeStamp aNextTimeout)
 {
+  TimeDuration nextTimeoutDuration = aNextTimeout - TimeStamp::Now();
   PR_LOG(sLog, PR_LOG_DEBUG,
-         ("idleService: SetTimerExpiryIfBefore: next timeout %lld usec",
-          aNextTimeoutInPR));
+         ("idleService: SetTimerExpiryIfBefore: next timeout %0.f msec from now",
+          nextTimeoutDuration.ToMilliseconds()));
 #ifdef ANDROID
   __android_log_print(ANDROID_LOG_INFO, "IdleService",
-                      "SetTimerExpiryIfBefore: next timeout %lld usec",
-                      aNextTimeoutInPR);
+                      "SetTimerExpiryIfBefore: next timeout %0.f msec from now",
+                      nextTimeoutDuration.ToMilliseconds());
 #endif
 
   // Bail if we don't have a timer service.
   if (!mTimer) {
     return;
   }
 
   // If the new timeout is before the old one or we don't have a timer running,
   // then restart the timer.
-  if (mCurrentlySetToTimeoutAtInPR > aNextTimeoutInPR ||
-      !mCurrentlySetToTimeoutAtInPR) {
+  if (mCurrentlySetToTimeoutAt.IsNull() ||
+      mCurrentlySetToTimeoutAt > aNextTimeout) {
 
-#if defined(PR_LOGGING) || defined(ANDROID)
-    PRTime oldTimeout = mCurrentlySetToTimeoutAtInPR;
-#endif
-
-    mCurrentlySetToTimeoutAtInPR = aNextTimeoutInPR ;
+    mCurrentlySetToTimeoutAt = aNextTimeout;
 
     // Stop the current timer (it's ok to try'n stop it, even it isn't running).
     mTimer->Cancel();
 
     // Check that the timeout is actually in the future, otherwise make it so.
-    PRTime currentTimeInPR = PR_Now();
-    if (currentTimeInPR > mCurrentlySetToTimeoutAtInPR) {
-      mCurrentlySetToTimeoutAtInPR = currentTimeInPR;
+    TimeStamp currentTime = TimeStamp::Now();
+    if (currentTime > mCurrentlySetToTimeoutAt) {
+      mCurrentlySetToTimeoutAt = currentTime;
     }
 
     // Add 10 ms to ensure we don't undershoot, and never get a "0" timer.
-    mCurrentlySetToTimeoutAtInPR += 10 * PR_USEC_PER_MSEC;
+    mCurrentlySetToTimeoutAt += TimeDuration::FromMilliseconds(10);
 
+    TimeDuration deltaTime = mCurrentlySetToTimeoutAt - currentTime;
     PR_LOG(sLog, PR_LOG_DEBUG,
-           ("idleService: reset timer expiry from %lld usec to %lld usec",
-            oldTimeout, mCurrentlySetToTimeoutAtInPR));
+           ("idleService: IdleService", "reset timer expiry to %0.f msec from now",
+            deltaTime.ToMilliseconds()));
 #ifdef ANDROID
-  __android_log_print(ANDROID_LOG_INFO, "IdleService",
-                      "reset timer expiry from %lld usec to %lld usec",
-                      oldTimeout, mCurrentlySetToTimeoutAtInPR);
+    __android_log_print(ANDROID_LOG_INFO, "IdleService",
+                        "reset timer expiry to %0.f msec from now",
+                        deltaTime.ToMilliseconds());
 #endif
 
     // Start the timer
     mTimer->InitWithFuncCallback(StaticIdleTimerCallback,
                                  this,
-                                 (mCurrentlySetToTimeoutAtInPR -
-                                  currentTimeInPR) / PR_USEC_PER_MSEC,
+                                 deltaTime.ToMilliseconds(),
                                  nsITimer::TYPE_ONE_SHOT);
 
   }
 }
 
 
 void
 nsIdleService::ReconfigureTimer(void)
@@ -833,45 +831,43 @@ nsIdleService::ReconfigureTimer(void)
 #endif
     return;
   }
 
   // Find the next timeout value, assuming we are not polling.
 
   // We need to store the current time, so we don't get artifacts from the time
   // ticking while we are processing.
-  PRTime curTimeInPR = PR_Now();
+  TimeStamp curTime = TimeStamp::Now();
+
+  TimeStamp nextTimeoutAt = mLastUserInteraction +
+                            TimeDuration::FromSeconds(mDeltaToNextIdleSwitchInS);
 
-  PRTime nextTimeoutAtInPR = mLastUserInteractionInPR +
-                             (((PRTime)mDeltaToNextIdleSwitchInS) *
-                              PR_USEC_PER_SEC);
-
+  TimeDuration nextTimeoutDuration = nextTimeoutAt - curTime;
   PR_LOG(sLog, PR_LOG_DEBUG,
-         ("idleService: next timeout %lld usec (%u msec from now)",
-          nextTimeoutAtInPR,
-          (uint32_t)((nextTimeoutAtInPR - curTimeInPR) / PR_USEC_PER_MSEC)));
+         ("idleService: next timeout %0.f msec from now",
+          nextTimeoutDuration.ToMilliseconds()));
 #ifdef ANDROID
   __android_log_print(ANDROID_LOG_INFO, "IdleService",
-                      "next timeout %lld usec (%lld msec from now)",
-                      nextTimeoutAtInPR,
-                      ((nextTimeoutAtInPR - curTimeInPR) / PR_USEC_PER_MSEC));
+                      "next timeout %0.f msec from now",
+                      nextTimeoutDuration.ToMilliseconds());
 #endif
   // Check if we should correct the timeout time because we should poll before.
   if (mAnyObserverIdle && UsePollMode()) {
-    PRTime pollTimeout = curTimeInPR +
-                         MIN_IDLE_POLL_INTERVAL_MSEC * PR_USEC_PER_MSEC;
+    TimeStamp pollTimeout =
+        curTime + TimeDuration::FromMilliseconds(MIN_IDLE_POLL_INTERVAL_MSEC);
 
-    if (nextTimeoutAtInPR > pollTimeout) {
+    if (nextTimeoutAt > pollTimeout) {
       PR_LOG(sLog, PR_LOG_DEBUG,
            ("idleService: idle observers, reducing timeout to %u msec from now",
             MIN_IDLE_POLL_INTERVAL_MSEC));
 #ifdef ANDROID
       __android_log_print(ANDROID_LOG_INFO, "IdleService",
                           "idle observers, reducing timeout to %u msec from now",
                           MIN_IDLE_POLL_INTERVAL_MSEC);
 #endif
-      nextTimeoutAtInPR = pollTimeout;
+      nextTimeoutAt = pollTimeout;
     }
   }
 
-  SetTimerExpiryIfBefore(nextTimeoutAtInPR);
+  SetTimerExpiryIfBefore(nextTimeoutAt);
 }
 
--- a/widget/xpwidgets/nsIdleService.h
+++ b/widget/xpwidgets/nsIdleService.h
@@ -11,16 +11,17 @@
 #include "nsIIdleServiceInternal.h"
 #include "nsCOMPtr.h"
 #include "nsITimer.h"
 #include "nsTArray.h"
 #include "nsIObserver.h"
 #include "nsIIdleService.h"
 #include "nsCategoryCache.h"
 #include "nsWeakReference.h"
+#include "mozilla/TimeStamp.h"
 
 /**
  * Class we can use to store an observer with its associated idle time
  * requirement and whether or not the observer thinks it's "idle".
  */
 class IdleListener {
 public:
   nsCOMPtr<nsIObserver> observer;
@@ -150,25 +151,25 @@ protected:
   virtual bool UsePollMode();
 
 private:
   /**
    * Ensure that the timer is expiring at least at the given time
    *
    * The function might not restart the timer if there is one running currently
    *
-   * @param aNextTimeoutInPR
+   * @param aNextTimeout
    *        The last absolute time the timer should expire
    */
-  void SetTimerExpiryIfBefore(PRTime aNextTimeoutInPR);
+  void SetTimerExpiryIfBefore(mozilla::TimeStamp aNextTimeout);
 
   /**
    * Stores the next timeout time, 0 means timer not running
    */
-  PRTime mCurrentlySetToTimeoutAtInPR;
+  mozilla::TimeStamp mCurrentlySetToTimeoutAt;
 
   /**
    * mTimer holds the internal timer used by this class to detect when to poll
    * for idle time, when to check if idle timers should expire etc.
    */
   nsCOMPtr<nsITimer> mTimer;
 
   /**
@@ -194,17 +195,17 @@ private:
    *
    * If this value is 0 it means there are no active observers
    */
   uint32_t mDeltaToNextIdleSwitchInS;
 
   /**
    * Absolute value for when the last user interaction took place.
    */
-  PRTime mLastUserInteractionInPR;
+  mozilla::TimeStamp mLastUserInteraction;
 
 
   /**
    * Function that ensures the timer is running with at least the minimum time
    * needed.  It will kill the timer if there are no active observers.
    */
   void ReconfigureTimer(void);