Timer alignment in separate web processes should not all sync up to the same point.
authorbarraclough@apple.com <barraclough@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 1 Mar 2016 23:33:36 +0000 (23:33 +0000)
committerbarraclough@apple.com <barraclough@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 1 Mar 2016 23:33:36 +0000 (23:33 +0000)
https://bugs.webkit.org/show_bug.cgi?id=154878

Reviewed by Chris Dumez.

For any given WebContent process it is desirable that timers are synchronized to a single
alignment point, but if all WebContent processes align to the same point then there may
be a thundering herd of processes waking up.

* page/DOMTimer.cpp:
(WebCore::DOMTimer::alignedFireTime):
    - align to a randomized point.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@197415 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/page/DOMTimer.cpp

index 3277255..460e6fe 100644 (file)
@@ -1,3 +1,18 @@
+2016-03-01  Gavin Barraclough  <barraclough@apple.com>
+
+        Timer alignment in separate web processes should not all sync up to the same point.
+        https://bugs.webkit.org/show_bug.cgi?id=154878
+
+        Reviewed by Chris Dumez.
+
+        For any given WebContent process it is desirable that timers are synchronized to a single
+        alignment point, but if all WebContent processes align to the same point then there may
+        be a thundering herd of processes waking up.
+
+        * page/DOMTimer.cpp:
+        (WebCore::DOMTimer::alignedFireTime):
+            - align to a randomized point.
+
 2016-03-01  Alex Christensen  <achristensen@webkit.org>
 
         Reduce size of internal windows build output
index e05892f..26bea5d 100644 (file)
@@ -40,6 +40,7 @@
 #include <wtf/HashMap.h>
 #include <wtf/MathExtras.h>
 #include <wtf/NeverDestroyed.h>
+#include <wtf/RandomNumber.h>
 #include <wtf/StdLibExtras.h>
 
 #if PLATFORM(IOS)
@@ -422,8 +423,15 @@ double DOMTimer::intervalClampedToMinimum() const
 
 double DOMTimer::alignedFireTime(double fireTime) const
 {
-    if (double alignmentInterval = scriptExecutionContext()->timerAlignmentInterval(m_nestingLevel >= maxTimerNestingLevel))
-        return ceil(fireTime / alignmentInterval) * alignmentInterval;
+    if (double alignmentInterval = scriptExecutionContext()->timerAlignmentInterval(m_nestingLevel >= maxTimerNestingLevel)) {
+        // Don't mess with zero-delay timers.
+        if (!fireTime)
+            return fireTime;
+        static const double randomizedAlignment = randomNumber();
+        // Force alignment to randomizedAlignment fraction of the way between alignemntIntervals, e.g.
+        // if alignmentInterval is 10 and randomizedAlignment is 0.3 this will align to 3, 13, 23, ...
+        return (ceil(fireTime / alignmentInterval - randomizedAlignment) + randomizedAlignment) * alignmentInterval;
+    }
 
     return fireTime;
 }