Changeset 240759 in webkit
- Timestamp:
- Jan 30, 2019 8:53:34 PM (5 years ago)
- Location:
- trunk/Source/WebKit
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit/ChangeLog
r240757 r240759 1 2019-01-30 Benjamin Poulain <benjamin@webkit.org> 2 3 <rdar://problem/47570443> Responsiveness timers are too expensive for frequent events 4 https://bugs.webkit.org/show_bug.cgi?id=194003 5 6 Reviewed by Geoffrey Garen. 7 8 The problem here is specific to wheel events. 9 10 For every wheel event, we start a responsiveness timer and send 11 a ping to the WebProcess. When the WebProcess respond, we stop the timer. 12 13 The cost of setting up the timers adds up since we get many events. 14 15 The first step to improve the situation was to switch ResponsivenessTimer 16 to WebCore::Timer. Since WebCore::Timer reuse the same CFRunLoopTimerRef, 17 we save the allocation/deallocation, insertion in the event loop, etc. 18 19 Using WebCore::Timer saves some instructions but we were still hitting 20 the kernel at 120hz to set up then kill each timer. 21 The second improvement of the patch is to avoid that by not killing the timer 22 when we hear back from the WebProcess. 23 24 Instead of killing the timer, we let it run and ignore the result. 25 When the next event comes, we reschedule the existing timer. 26 This brings down the timers to 60Hz, the same rate as the events. 27 28 The very last event does time out. In that case, we have a bad idle wake up: 29 we wake up a sleeping CPU do do nothing. 30 In the case of wheel events, this is fine since we saved a bunch of CPU already. 31 For all the other cases, I kept the normal operating mode to avoid the idle wake. 32 33 * UIProcess/ResponsivenessTimer.cpp: 34 (WebKit::ResponsivenessTimer::ResponsivenessTimer): 35 (WebKit::ResponsivenessTimer::invalidate): 36 (WebKit::ResponsivenessTimer::timerFired): 37 (WebKit::ResponsivenessTimer::start): 38 (WebKit::ResponsivenessTimer::startWithLazyStop): 39 (WebKit::ResponsivenessTimer::stop): 40 (WebKit::ResponsivenessTimer::processTerminated): 41 (WebKit::ResponsivenessTimer::~ResponsivenessTimer): Deleted. 42 * UIProcess/ResponsivenessTimer.h: 43 * UIProcess/WebPageProxy.cpp: 44 (WebKit::WebPageProxy::sendWheelEvent): 45 * UIProcess/WebProcessProxy.cpp: 46 (WebKit::WebProcessProxy::isResponsiveWithLazyStop): 47 * UIProcess/WebProcessProxy.h: 48 1 49 2019-01-30 Daniel Bates <dabates@apple.com> 2 50 -
trunk/Source/WebKit/UIProcess/ResponsivenessTimer.cpp
r215173 r240759 33 33 ResponsivenessTimer::ResponsivenessTimer(ResponsivenessTimer::Client& client) 34 34 : m_client(client) 35 , m_isResponsive(true) 36 , m_timer(RunLoop::main(), this, &ResponsivenessTimer::timerFired) 35 , m_timer(*this, &ResponsivenessTimer::timerFired) 37 36 { 38 37 } 39 38 40 ResponsivenessTimer::~ResponsivenessTimer() 41 { 42 m_timer.stop(); 43 } 39 ResponsivenessTimer::~ResponsivenessTimer() = default; 44 40 45 41 void ResponsivenessTimer::invalidate() 46 42 { 43 m_waitingForTimer = false; 44 m_useLazyStop = false; 47 45 m_timer.stop(); 48 46 } … … 50 48 void ResponsivenessTimer::timerFired() 51 49 { 50 if (!m_waitingForTimer) 51 return; 52 53 m_waitingForTimer = false; 54 m_useLazyStop = false; 55 52 56 if (!m_isResponsive) 53 57 return; 54 58 55 59 if (!m_client.mayBecomeUnresponsive()) { 60 m_waitingForTimer = true; 56 61 m_timer.startOneShot(responsivenessTimeout); 57 62 return; … … 67 72 void ResponsivenessTimer::start() 68 73 { 69 if (m_ timer.isActive())74 if (m_waitingForTimer) 70 75 return; 71 76 77 m_waitingForTimer = true; 78 m_useLazyStop = false; 72 79 m_timer.startOneShot(responsivenessTimeout); 80 } 81 82 void ResponsivenessTimer::startWithLazyStop() 83 { 84 if (!m_waitingForTimer) { 85 start(); 86 m_useLazyStop = true; 87 } 73 88 } 74 89 … … 84 99 } 85 100 86 m_timer.stop(); 101 m_waitingForTimer = false; 102 103 if (m_useLazyStop) 104 m_useLazyStop = false; 105 else 106 m_timer.stop(); 87 107 } 88 108 … … 90 110 { 91 111 // Since there is no web process, we must not be waiting for it anymore. 92 stop(); 112 m_waitingForTimer = false; 113 m_timer.stop(); 93 114 } 94 115 -
trunk/Source/WebKit/UIProcess/ResponsivenessTimer.h
r213824 r240759 27 27 #define ResponsivenessTimer_h 28 28 29 #include < wtf/RunLoop.h>29 #include <WebCore/Timer.h> 30 30 31 31 namespace WebKit { … … 49 49 50 50 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 51 62 void stop(); 52 63 … … 61 72 62 73 ResponsivenessTimer::Client& m_client; 63 bool m_isResponsive; 64 65 RunLoop::Timer<ResponsivenessTimer> m_timer; 74 WebCore::Timer m_timer; 75 bool m_isResponsive { true }; 76 bool m_waitingForTimer { false }; 77 bool m_useLazyStop { false }; 66 78 }; 67 79 -
trunk/Source/WebKit/UIProcess/WebPageProxy.cpp
r240725 r240759 2358 2358 // Manually ping the web process to check for responsiveness since our wheel 2359 2359 // event will dispatch to a non-main thread, which always responds. 2360 m_process->isResponsive (nullptr);2360 m_process->isResponsiveWithLazyStop(); 2361 2361 } 2362 2362 -
trunk/Source/WebKit/UIProcess/WebProcessProxy.cpp
r240683 r240759 1118 1118 } 1119 1119 1120 void WebProcessProxy::isResponsiveWithLazyStop() 1121 { 1122 if (m_isResponsive == NoOrMaybe::No) 1123 return; 1124 1125 responsivenessTimer().startWithLazyStop(); 1126 send(Messages::WebProcess::MainThreadPing(), 0); 1127 } 1128 1120 1129 bool WebProcessProxy::isJITEnabled() const 1121 1130 { -
trunk/Source/WebKit/UIProcess/WebProcessProxy.h
r240683 r240759 207 207 208 208 void isResponsive(WTF::Function<void(bool isWebProcessResponsive)>&&); 209 void isResponsiveWithLazyStop(); 209 210 void didReceiveMainThreadPing(); 210 211 void didReceiveBackgroundResponsivenessPing();
Note: See TracChangeset
for help on using the changeset viewer.