Bug 1437167 - Part 2: Round submillisecond condition variable waits up to 1ms, r=froydnj
authorNika Layzell <nika@thelayzells.com>
Fri, 09 Feb 2018 16:44:18 -0500
changeset 412648 76ac0b53d77120f59f74c8015608c7efb8f09924
parent 412647 b044c550a87505347b4b9cd93ccfffb7fd0dc291
child 412649 dc2973a36696cc8441a091d11bff21d0584760d7
push id101979
push usernika@thelayzells.com
push dateTue, 10 Apr 2018 21:51:07 +0000
treeherdermozilla-inbound@bb10a801252a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1437167
milestone61.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 1437167 - Part 2: Round submillisecond condition variable waits up to 1ms, r=froydnj
mozglue/misc/ConditionVariable_windows.cpp
--- a/mozglue/misc/ConditionVariable_windows.cpp
+++ b/mozglue/misc/ConditionVariable_windows.cpp
@@ -58,27 +58,41 @@ mozilla::detail::ConditionVariableImpl::
   bool r = SleepConditionVariableCS(&platformData()->cv_, cs, INFINITE);
   MOZ_RELEASE_ASSERT(r);
 }
 
 mozilla::CVStatus
 mozilla::detail::ConditionVariableImpl::wait_for(MutexImpl& lock,
                                                  const mozilla::TimeDuration& rel_time)
 {
+  if (rel_time == mozilla::TimeDuration::Forever()) {
+    wait(lock);
+    return CVStatus::NoTimeout;
+  }
+
   CRITICAL_SECTION* cs = &lock.platformData()->criticalSection;
 
-  // Note that DWORD is unsigned, so we have to be careful to clamp at 0.
-  // If rel_time is Forever, then ToMilliseconds is +inf, which evaluates as
-  // greater than UINT32_MAX, resulting in the correct INFINITE wait.
+  // Note that DWORD is unsigned, so we have to be careful to clamp at 0. If
+  // rel_time is Forever, then ToMilliseconds is +inf, which evaluates as
+  // greater than UINT32_MAX, resulting in the correct INFINITE wait. We also
+  // don't want to round sub-millisecond waits to 0, as that wastes energy (see
+  // bug 1437167 comment 6), so we instead round submillisecond waits to 1ms.
   double msecd = rel_time.ToMilliseconds();
-  DWORD msec = msecd < 0.0
-               ? 0
-               : msecd > UINT32_MAX
-                 ? INFINITE
-                 : static_cast<DWORD>(msecd);
+  DWORD msec;
+  if (msecd < 0.0) {
+    msec = 0;
+  } else if (msecd > UINT32_MAX) {
+    msec = INFINITE;
+  } else {
+    msec = static_cast<DWORD>(msecd);
+    // Round submillisecond waits to 1ms.
+    if (msec == 0 && !rel_time.IsZero()) {
+      msec = 1;
+    }
+  }
 
   BOOL r = SleepConditionVariableCS(&platformData()->cv_, cs, msec);
   if (r)
     return CVStatus::NoTimeout;
   MOZ_RELEASE_ASSERT(GetLastError() == ERROR_TIMEOUT);
   return CVStatus::Timeout;
 }