Changeset 143210 in webkit


Ignore:
Timestamp:
Feb 18, 2013 6:28:28 AM (11 years ago)
Author:
Antti Koivisto
Message:

Reschedule shared CFRunLoopTimer instead of reconstructing it
https://bugs.webkit.org/show_bug.cgi?id=109765

Reviewed by Andreas Kling.

Using CFRunLoopTimerSetNextFireDate is over 2x faster than deleting and reconstructing timers.

  • platform/SharedTimer.h:

(WebCore::SharedTimer::willEnterNestedEventLoop):
(WebCore):
(MainThreadSharedTimer):
(WebCore::MainThreadSharedTimer::willEnterNestedEventLoop):

  • platform/ThreadTimers.cpp:

(WebCore::ThreadTimers::fireTimersInNestedEventLoop):

  • platform/mac/SharedTimerMac.mm:

(WebCore):
(WebCore::PowerObserver::clearSharedTimer):
(WebCore::ensurePowerObserver):
(WebCore::sharedTimer):
(WebCore::reinsertSharedTimer):

Before entering nested runloop (used for inspector debugger mostly) reconstruct and reinsert the timer. For some reason
the timer doesn't fire otherwise.

(WebCore::setSharedTimerFireInterval):
(WebCore::stopSharedTimer):

Location:
trunk/Source/WebCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r143209 r143210  
     12013-02-16  Antti Koivisto  <antti@apple.com>
     2
     3        Reschedule shared CFRunLoopTimer instead of reconstructing it
     4        https://bugs.webkit.org/show_bug.cgi?id=109765
     5
     6        Reviewed by Andreas Kling.
     7
     8        Using CFRunLoopTimerSetNextFireDate is over 2x faster than deleting and reconstructing timers.
     9
     10        * platform/SharedTimer.h:
     11        (WebCore::SharedTimer::willEnterNestedEventLoop):
     12        (WebCore):
     13        (MainThreadSharedTimer):
     14        (WebCore::MainThreadSharedTimer::willEnterNestedEventLoop):
     15        * platform/ThreadTimers.cpp:
     16        (WebCore::ThreadTimers::fireTimersInNestedEventLoop):
     17        * platform/mac/SharedTimerMac.mm:
     18        (WebCore):
     19        (WebCore::PowerObserver::clearSharedTimer):
     20        (WebCore::ensurePowerObserver):
     21        (WebCore::sharedTimer):
     22        (WebCore::reinsertSharedTimer):
     23       
     24            Before entering nested runloop (used for inspector debugger mostly) reconstruct and reinsert the timer. For some reason
     25            the timer doesn't fire otherwise.
     26
     27        (WebCore::setSharedTimerFireInterval):
     28        (WebCore::stopSharedTimer):
     29
    1302013-02-18  Alexander Pavlov  <apavlov@chromium.org>
    231
  • trunk/Source/WebCore/platform/SharedTimer.h

    r91206 r143210  
    4545        virtual void setFireInterval(double) = 0;
    4646        virtual void stop() = 0;
     47        virtual void willEnterNestedEventLoop() { ASSERT_NOT_REACHED(); }
    4748    };
    4849
     
    5354    void setSharedTimerFireInterval(double);
    5455    void stopSharedTimer();
    55 
     56#if PLATFORM(MAC)
     57    void clearSharedTimer();
     58#endif
    5659    // Implementation of SharedTimer for the main thread.
    5760    class MainThreadSharedTimer : public SharedTimer {
     
    7174            stopSharedTimer();
    7275        }
     76
     77        virtual void willEnterNestedEventLoop()
     78        {
     79#if PLATFORM(MAC)
     80            clearSharedTimer();
     81#endif
     82        }
    7383    };
    7484
  • trunk/Source/WebCore/platform/ThreadTimers.cpp

    r142811 r143210  
    143143    // Reset the reentrancy guard so the timers can fire again.
    144144    m_firingTimers = false;
     145    m_sharedTimer->willEnterNestedEventLoop();
    145146    updateSharedTimer();
    146147}
  • trunk/Source/WebCore/platform/mac/SharedTimerMac.mm

    r142907 r143210  
    4343namespace WebCore {
    4444
    45 static CFRunLoopTimerRef sharedTimer;
     45static const CFTimeInterval distantFuture = 60 * 60 * 24 * 365 * 10; // Decade.
    4646static void (*sharedTimerFiredFunction)();
    4747static void timerFired(CFRunLoopTimerRef, void*);
     
    144144    ASSERT(CFRunLoopGetCurrent() == CFRunLoopGetMain());
    145145
    146     if (!sharedTimer)
    147         return;
    148 
    149146    stopSharedTimer();
    150147    timerFired(0, 0);
    151148}
    152149
    153 static PowerObserver* PowerObserver;
     150static void ensurePowerObserver()
     151{
     152    static dispatch_once_t onceToken;
     153    dispatch_once(&onceToken, ^{
     154        static PowerObserver* powerObserver;
     155        powerObserver = PowerObserver::create().leakPtr();
     156    });
     157}
     158
     159static CFRunLoopTimerRef globalSharedTimer;
     160
     161static CFRunLoopTimerRef sharedTimer()
     162{
     163    if (!globalSharedTimer) {
     164        globalSharedTimer = CFRunLoopTimerCreate(0, CFAbsoluteTimeGetCurrent() + distantFuture, distantFuture, 0, 0, timerFired, 0);
     165        CFRunLoopAddTimer(CFRunLoopGetCurrent(), globalSharedTimer, kCFRunLoopCommonModes);
     166        ensurePowerObserver();
     167    }
     168    return globalSharedTimer;
     169};
     170
     171void clearSharedTimer()
     172{
     173    // For some reason the timer won't fire in a nested runloop unless it has been freshly created and inserted.
     174    CFRunLoopTimerInvalidate(globalSharedTimer);
     175    CFRelease(globalSharedTimer);
     176    globalSharedTimer = 0;
     177}
    154178
    155179void setSharedTimerFiredFunction(void (*f)())
     
    171195{
    172196    ASSERT(sharedTimerFiredFunction);
    173 
    174     if (sharedTimer) {
    175         CFRunLoopTimerInvalidate(sharedTimer);
    176         CFRelease(sharedTimer);
    177     }
    178 
    179197    CFAbsoluteTime fireDate = CFAbsoluteTimeGetCurrent() + interval;
    180     sharedTimer = CFRunLoopTimerCreate(0, fireDate, 0, 0, 0, timerFired, 0);
    181     CFRunLoopAddTimer(CFRunLoopGetCurrent(), sharedTimer, kCFRunLoopCommonModes);
    182    
    183     if (!PowerObserver)
    184         PowerObserver = PowerObserver::create().leakPtr();
     198    CFRunLoopTimerSetNextFireDate(sharedTimer(), fireDate);
    185199}
    186200
    187201void stopSharedTimer()
    188202{
    189     if (sharedTimer) {
    190         CFRunLoopTimerInvalidate(sharedTimer);
    191         CFRelease(sharedTimer);
    192         sharedTimer = 0;
    193     }
     203    CFRunLoopTimerSetNextFireDate(sharedTimer(), CFAbsoluteTimeGetCurrent() + distantFuture);
    194204}
    195205
Note: See TracChangeset for help on using the changeset viewer.