Changeset 241113 in webkit


Ignore:
Timestamp:
Feb 6, 2019 7:13:11 PM (5 years ago)
Author:
benjamin@webkit.org
Message:

Unreviewed, rolling out r240759 and r240944.

Some timer uses are done off the main thread, WebCore::Timer
cannot be used

Reverted changesets:

"<rdar://problem/47570443> Responsiveness timers are too
expensive for frequent events"
https://bugs.webkit.org/show_bug.cgi?id=194003
https://trac.webkit.org/changeset/240759

"Use deferrable timer to restart the Responsiveness Timer on
each wheel event"
https://bugs.webkit.org/show_bug.cgi?id=194135
https://trac.webkit.org/changeset/240944

Location:
trunk/Source
Files:
16 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r241111 r241113  
     12019-02-06  Benjamin Poulain  <benjamin@webkit.org>
     2
     3        Unreviewed, rolling out r240759 and r240944.
     4
     5        Some timer uses are done off the main thread, WebCore::Timer
     6        cannot be used
     7
     8        Reverted changesets:
     9
     10        "<rdar://problem/47570443> Responsiveness timers are too
     11        expensive for frequent events"
     12        https://bugs.webkit.org/show_bug.cgi?id=194003
     13        https://trac.webkit.org/changeset/240759
     14
     15        "Use deferrable timer to restart the Responsiveness Timer on
     16        each wheel event"
     17        https://bugs.webkit.org/show_bug.cgi?id=194135
     18        https://trac.webkit.org/changeset/240944
     19
    1202019-02-06  Keith Rollin  <krollin@apple.com>
    221
  • trunk/Source/WebCore/css/CSSImageGeneratorValue.cpp

    r240944 r241113  
    5757    const FloatSize m_size;
    5858    const Ref<GeneratedImage> m_image;
    59     ResettableOneShotTimer m_evictionTimer;
     59    DeferrableOneShotTimer m_evictionTimer;
    6060};
    6161
  • trunk/Source/WebCore/html/HTMLPlugInImageElement.h

    r240944 r241113  
    131131    bool m_needsDocumentActivationCallbacks { false };
    132132    RefPtr<MouseEvent> m_pendingClickEventFromSnapshot;
    133     ResettableOneShotTimer m_simulatedMouseClickTimer;
     133    DeferrableOneShotTimer m_simulatedMouseClickTimer;
    134134    Timer m_removeSnapshotTimer;
    135135    RefPtr<Image> m_snapshotImage;
  • trunk/Source/WebCore/loader/cache/CachedResource.h

    r240944 r241113  
    312312    ResourceResponse m_response;
    313313
    314     ResettableOneShotTimer m_decodedDataDeletionTimer;
     314    DeferrableOneShotTimer m_decodedDataDeletionTimer;
    315315
    316316    // FIXME: Make the rest of these data members private and use functions in derived classes instead.
  • trunk/Source/WebCore/platform/Timer.cpp

    r240944 r241113  
    261261TimerBase::~TimerBase()
    262262{
    263     assertThreadSafety();
     263    ASSERT(canAccessThreadLocalDataForThread(m_thread.get()));
    264264    RELEASE_ASSERT(canAccessThreadLocalDataForThread(m_thread.get()) || shouldSuppressThreadSafetyCheck());
    265265    stop();
     
    274274void TimerBase::start(Seconds nextFireInterval, Seconds repeatInterval)
    275275{
    276     assertThreadSafety();
     276    ASSERT(canAccessThreadLocalDataForThread(m_thread.get()));
    277277
    278278    m_repeatInterval = repeatInterval;
     
    282282void TimerBase::stop()
    283283{
    284     assertThreadSafety();
     284    ASSERT(canAccessThreadLocalDataForThread(m_thread.get()));
    285285
    286286    m_repeatInterval = 0_s;
     
    466466void TimerBase::setNextFireTime(MonotonicTime newTime)
    467467{
    468     assertThreadSafety();
     468    ASSERT(canAccessThreadLocalDataForThread(m_thread.get()));
    469469    RELEASE_ASSERT(canAccessThreadLocalDataForThread(m_thread.get()) || shouldSuppressThreadSafetyCheck());
    470470    RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(!m_wasDeleted);
     
    521521}
    522522
    523 DeferrableOneShotTimer::DeferrableOneShotTimer(WTF::Function<void()>&& function)
    524     : m_function(WTFMove(function))
    525 {
    526 }
    527 
    528 DeferrableOneShotTimer::~DeferrableOneShotTimer() = default;
    529 
    530 void DeferrableOneShotTimer::startOneShot(Seconds interval)
    531 {
    532     assertThreadSafety();
    533 
    534     MonotonicTime oldNextFireTime = TimerBase::nextFireTime();
    535     if (!oldNextFireTime) {
    536         m_restartFireTime = MonotonicTime();
    537         TimerBase::startOneShot(interval);
    538         return;
    539     }
    540 
    541     MonotonicTime newNextFireTime = MonotonicTime::now() + interval;
    542     if (newNextFireTime < oldNextFireTime) {
    543         m_restartFireTime = MonotonicTime();
    544         TimerBase::setNextFireTime(newNextFireTime);
    545         return;
    546     }
    547 
    548     m_restartFireTime = newNextFireTime;
    549 }
    550 
    551 void DeferrableOneShotTimer::stop()
    552 {
    553     TimerBase::stop();
    554 }
    555 
    556 void DeferrableOneShotTimer::fired()
    557 {
    558     if (m_restartFireTime) {
    559         MonotonicTime now = MonotonicTime::now();
    560         MonotonicTime restartFireTime = m_restartFireTime;
    561         m_restartFireTime = MonotonicTime();
    562         if (now < restartFireTime) {
    563             TimerBase::setNextFireTime(restartFireTime);
    564             return;
    565         }
    566     }
    567 
    568     m_function();
    569 }
    570 
    571523} // namespace WebCore
    572524
  • trunk/Source/WebCore/platform/Timer.h

    r240944 r241113  
    6969    static void fireTimersInNestedEventLoop();
    7070
    71 protected:
    72     MonotonicTime nextFireTime() const { return m_heapItem ? m_heapItem->time : MonotonicTime { }; }
    73     void setNextFireTime(MonotonicTime);
    74 
    75     void assertThreadSafety()
    76     {
    77         ASSERT(canAccessThreadLocalDataForThread(m_thread.get()));
    78     }
    79 
    8071private:
    8172    virtual void fired() = 0;
     
    8576    void checkConsistency() const;
    8677    void checkHeapIndex() const;
     78
     79    void setNextFireTime(MonotonicTime);
    8780
    8881    bool inHeap() const { return m_heapItem && m_heapItem->isInHeap(); }
     
    9992    void heapPopMin();
    10093    static void heapDeleteNullMin(ThreadTimerHeap&);
     94
     95    MonotonicTime nextFireTime() const { return m_heapItem ? m_heapItem->time : MonotonicTime { }; }
    10196
    10297    MonotonicTime m_unalignedNextFireTime; // m_nextFireTime not considering alignment interval
     
    147142}
    148143
    149 // ResettableOneShotTimer is a optimization for timers that need to be delayed frequently.
    150 //
    151 // Changing the deadline of a timer is not a cheap operation. When it is done frequently, it can
    152 // affect performance.
    153 //
    154 // With ResettableOneShotTimer, calling restart() does not change the underlying timer.
    155 // Instead, when the underlying timer fires, a new dealine is set for "delay" seconds.
    156 //
    157 // When a ResettableOneShotTimer of 5 seconds is restarted before the deadline, the total
    158 // time before the function is called is 10 seconds.
    159 //
    160 // If a timer is unfrequently reset, or if it is usually stopped before the deadline,
    161 // prefer WebCore::Timer to avoid idle wake-up.
    162 class ResettableOneShotTimer : protected TimerBase {
     144class DeferrableOneShotTimer : protected TimerBase {
    163145    WTF_MAKE_FAST_ALLOCATED;
    164146public:
    165147    template<typename TimerFiredClass>
    166     ResettableOneShotTimer(TimerFiredClass& object, void (TimerFiredClass::*function)(), Seconds delay)
    167         : ResettableOneShotTimer(std::bind(function, &object), delay)
     148    DeferrableOneShotTimer(TimerFiredClass& object, void (TimerFiredClass::*function)(), Seconds delay)
     149        : DeferrableOneShotTimer(std::bind(function, &object), delay)
    168150    {
    169151    }
    170152
    171     ResettableOneShotTimer(WTF::Function<void()>&& function, Seconds delay)
     153    DeferrableOneShotTimer(WTF::Function<void ()>&& function, Seconds delay)
    172154        : m_function(WTFMove(function))
    173155        , m_delay(delay)
     
    215197};
    216198
    217 // DeferrableOneShotTimer is a optimization for timers that need to change the deadline frequently.
    218 //
    219 // With DeferrableOneShotTimer, if the new deadline is later than the original deadline, the timer
    220 // is not reset. Instead, the timer fires and schedule a new timer for the remaining time.
    221 //
    222 // DeferrableOneShotTimer supports absolute deadlines.
    223 // If a timer of 5 seconds is restarted after 2 seconds, the total time will be 7 seconds.
    224 //
    225 // Restarting a DeferrableOneShotTimer is more expensive than restarting a ResettableOneShotTimer.
    226 // If accumulating the delay is not important, prefer ResettableOneShotTimer.
    227 class WEBCORE_EXPORT DeferrableOneShotTimer : private TimerBase {
    228     WTF_MAKE_FAST_ALLOCATED;
    229 public:
    230     DeferrableOneShotTimer(WTF::Function<void()>&&);
    231     ~DeferrableOneShotTimer();
    232 
    233     void startOneShot(Seconds interval);
    234     void stop();
    235 
    236 private:
    237     void fired() override;
    238 
    239     WTF::Function<void()> m_function;
    240     MonotonicTime m_restartFireTime;
    241 };
    242 
    243199}
  • trunk/Source/WebCore/platform/graphics/ca/TileController.h

    r240944 r241113  
    208208
    209209    Timer m_tileRevalidationTimer;
    210     ResettableOneShotTimer m_tileSizeChangeTimer;
     210    DeferrableOneShotTimer m_tileSizeChangeTimer;
    211211
    212212    TileCoverage m_tileCoverage { CoverageForVisibleArea };
  • trunk/Source/WebCore/platform/graphics/cg/SubimageCacheWithTimer.h

    r240944 r241113  
    9595    HashCountedSet<CGImageRef> m_images;
    9696    SubimageCacheHashSet m_cache;
    97     ResettableOneShotTimer m_timer;
     97    DeferrableOneShotTimer m_timer;
    9898
    9999    static SubimageCacheWithTimer& subimageCache();
  • trunk/Source/WebKit/ChangeLog

    r241112 r241113  
     12019-02-06  Benjamin Poulain  <benjamin@webkit.org>
     2
     3        Unreviewed, rolling out r240759 and r240944.
     4
     5        Some timer uses are done off the main thread, WebCore::Timer
     6        cannot be used
     7
     8        Reverted changesets:
     9
     10        "<rdar://problem/47570443> Responsiveness timers are too
     11        expensive for frequent events"
     12        https://bugs.webkit.org/show_bug.cgi?id=194003
     13        https://trac.webkit.org/changeset/240759
     14
     15        "Use deferrable timer to restart the Responsiveness Timer on
     16        each wheel event"
     17        https://bugs.webkit.org/show_bug.cgi?id=194135
     18        https://trac.webkit.org/changeset/240944
     19
    1202019-02-06  chris fleizach  <cfleizach@apple.com>
    221
  • trunk/Source/WebKit/NetworkProcess/watchos/NetworkProximityAssertion.h

    r240944 r241113  
    8888    uint64_t m_assertionCount { 0 };
    8989    State m_state { State::Suspended };
    90     WebCore::ResettableOneShotTimer m_releaseTimer;
    91     WebCore::ResettableOneShotTimer m_suspendAfterBackgroundingTimer;
     90    WebCore::DeferrableOneShotTimer m_releaseTimer;
     91    WebCore::DeferrableOneShotTimer m_suspendAfterBackgroundingTimer;
    9292};
    9393
  • trunk/Source/WebKit/UIProcess/ResponsivenessTimer.cpp

    r240944 r241113  
    3333ResponsivenessTimer::ResponsivenessTimer(ResponsivenessTimer::Client& client)
    3434    : m_client(client)
    35     , m_timer(std::bind(&ResponsivenessTimer::timerFired, this))
     35    , m_isResponsive(true)
     36    , m_timer(RunLoop::main(), this, &ResponsivenessTimer::timerFired)
    3637{
    3738}
    3839
    39 ResponsivenessTimer::~ResponsivenessTimer() = default;
     40ResponsivenessTimer::~ResponsivenessTimer()
     41{
     42    m_timer.stop();
     43}
    4044
    4145void ResponsivenessTimer::invalidate()
    4246{
    43     m_waitingForTimer = false;
    44     m_useLazyStop = false;
    4547    m_timer.stop();
    4648}
     
    4850void ResponsivenessTimer::timerFired()
    4951{
    50     if (!m_waitingForTimer)
    51         return;
    52 
    53     m_waitingForTimer = false;
    54     m_useLazyStop = false;
    55 
    5652    if (!m_isResponsive)
    5753        return;
    5854
    5955    if (!m_client.mayBecomeUnresponsive()) {
    60         m_waitingForTimer = true;
    6156        m_timer.startOneShot(responsivenessTimeout);
    6257        return;
     
    7267void ResponsivenessTimer::start()
    7368{
    74     if (m_waitingForTimer)
     69    if (m_timer.isActive())
    7570        return;
    7671
    77     m_waitingForTimer = true;
    78     m_useLazyStop = false;
    7972    m_timer.startOneShot(responsivenessTimeout);
    80 }
    81 
    82 void ResponsivenessTimer::startWithLazyStop()
    83 {
    84     if (!m_waitingForTimer) {
    85         start();
    86         m_useLazyStop = true;
    87     }
    8873}
    8974
     
    9984    }
    10085
    101     m_waitingForTimer = false;
    102 
    103     if (m_useLazyStop)
    104         m_useLazyStop = false;
    105     else
    106         m_timer.stop();
     86    m_timer.stop();
    10787}
    10888
     
    11090{
    11191    // Since there is no web process, we must not be waiting for it anymore.
    112     m_waitingForTimer = false;
    113     m_timer.stop();
     92    stop();
    11493}
    11594
  • trunk/Source/WebKit/UIProcess/ResponsivenessTimer.h

    r240944 r241113  
    2727#define ResponsivenessTimer_h
    2828
    29 #include <WebCore/Timer.h>
     29#include <wtf/RunLoop.h>
    3030
    3131namespace WebKit {
     
    4949   
    5050    void start();
    51 
    52     // A responsiveness timer with lazy stop does not stop the underlying system timer when stopped.
    53     // Instead, it ignores the timeout if stop() was already called.
    54     //
    55     // This exists to reduce the rate at which we reset the timer.
    56     //
    57     // With a non lazy timer, we may set a timer and reset it soon after because the process is responsive.
    58     // For events, this means reseting a timer 120 times/s for a 60 Hz event source.
    59     // By not reseting the timer when responsive, we cut that in half to 60 timeout changes.
    60     void startWithLazyStop();
    61 
    6251    void stop();
    6352
     
    7261
    7362    ResponsivenessTimer::Client& m_client;
    74     WebCore::DeferrableOneShotTimer m_timer;
    75     bool m_isResponsive { true };
    76     bool m_waitingForTimer { false };
    77     bool m_useLazyStop { false };
     63    bool m_isResponsive;
     64
     65    RunLoop::Timer<ResponsivenessTimer> m_timer;
    7866};
    7967
  • trunk/Source/WebKit/UIProcess/WebPageProxy.cpp

    r241000 r241113  
    23582358    // Manually ping the web process to check for responsiveness since our wheel
    23592359    // event will dispatch to a non-main thread, which always responds.
    2360     m_process->isResponsiveWithLazyStop();
     2360    m_process->isResponsive(nullptr);
    23612361}
    23622362
  • trunk/Source/WebKit/UIProcess/WebProcessProxy.cpp

    r240954 r241113  
    11211121}
    11221122
    1123 void WebProcessProxy::isResponsiveWithLazyStop()
    1124 {
    1125     if (m_isResponsive == NoOrMaybe::No)
    1126         return;
    1127 
    1128     responsivenessTimer().startWithLazyStop();
    1129     send(Messages::WebProcess::MainThreadPing(), 0);
    1130 }
    1131 
    11321123bool WebProcessProxy::isJITEnabled() const
    11331124{
  • trunk/Source/WebKit/UIProcess/WebProcessProxy.h

    r240759 r241113  
    207207
    208208    void isResponsive(WTF::Function<void(bool isWebProcessResponsive)>&&);
    209     void isResponsiveWithLazyStop();
    210209    void didReceiveMainThreadPing();
    211210    void didReceiveBackgroundResponsivenessPing();
  • trunk/Source/WebKit/WebProcess/Plugins/PluginView.h

    r240944 r241113  
    285285    RefPtr<ShareableBitmap> m_transientPaintingSnapshot;
    286286    // This timer is used when plugin snapshotting is enabled, to capture a plugin placeholder.
    287     WebCore::ResettableOneShotTimer m_pluginSnapshotTimer;
     287    WebCore::DeferrableOneShotTimer m_pluginSnapshotTimer;
    288288#if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC) || PLATFORM(COCOA)
    289289    unsigned m_countSnapshotRetries { 0 };
Note: See TracChangeset for help on using the changeset viewer.