Title: [285159] trunk/Source
Revision
285159
Author
cdu...@apple.com
Date
2021-11-02 08:42:57 -0700 (Tue, 02 Nov 2021)

Log Message

Use higher QoS for WheelEvent and DisplayWasRefreshed IPCs
https://bugs.webkit.org/show_bug.cgi?id=232458
<rdar://82657744>

Reviewed by Simon Fraser.

Source/WebKit:

Use higher QoS for WheelEvent and DisplayWasRefreshed IPCs since those are high priority. The
UIProcess's main thread has high UserInteractive QoS but the IPC thread has a lower QoS by default.

We cannot raise the QoS of the IPC thread without regressing some performance benchmarks since not
all IPC is high priority.

Making this change helps with responsiveness under heavy load scenarios.

* Platform/IPC/Connection.cpp:
(IPC::Connection::sendMessage):
* Platform/IPC/Connection.h:
(IPC::Connection::send):
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::sendWheelEvent):
* UIProcess/mac/DisplayLink.cpp:
(WebKit::DisplayLink::notifyObserversDisplayWasRefreshed):

Source/WTF:

Add dispatchWithQOS() function to WorkQueue to dispatch a task with a given QoS.

* wtf/WorkQueue.cpp:
(WTF::WorkQueueBase::dispatchWithQOS):
* wtf/WorkQueue.h:
* wtf/cocoa/WorkQueueCocoa.cpp:
(WTF::WorkQueueBase::dispatchWithQOS):

Modified Paths

Diff

Modified: trunk/Source/WTF/ChangeLog (285158 => 285159)


--- trunk/Source/WTF/ChangeLog	2021-11-02 15:11:06 UTC (rev 285158)
+++ trunk/Source/WTF/ChangeLog	2021-11-02 15:42:57 UTC (rev 285159)
@@ -1,3 +1,19 @@
+2021-11-02  Chris Dumez  <cdu...@apple.com>
+
+        Use higher QoS for WheelEvent and DisplayWasRefreshed IPCs
+        https://bugs.webkit.org/show_bug.cgi?id=232458
+        <rdar://82657744>
+
+        Reviewed by Simon Fraser.
+
+        Add dispatchWithQOS() function to WorkQueue to dispatch a task with a given QoS.
+
+        * wtf/WorkQueue.cpp:
+        (WTF::WorkQueueBase::dispatchWithQOS):
+        * wtf/WorkQueue.h:
+        * wtf/cocoa/WorkQueueCocoa.cpp:
+        (WTF::WorkQueueBase::dispatchWithQOS):
+
 2021-11-01  Per Arne  <pvol...@apple.com>
 
         [macOS] Opening local html files is failing

Modified: trunk/Source/WTF/wtf/WorkQueue.cpp (285158 => 285159)


--- trunk/Source/WTF/wtf/WorkQueue.cpp	2021-11-02 15:11:06 UTC (rev 285158)
+++ trunk/Source/WTF/wtf/WorkQueue.cpp	2021-11-02 15:42:57 UTC (rev 285159)
@@ -81,6 +81,11 @@
     semaphore.wait();
 }
 
+void WorkQueueBase::dispatchWithQOS(Function<void()>&& function, QOS)
+{
+    dispatch(WTFMove(function));
+}
+
 void ConcurrentWorkQueue::apply(size_t iterations, WTF::Function<void(size_t index)>&& function)
 {
     if (!iterations)

Modified: trunk/Source/WTF/wtf/WorkQueue.h (285158 => 285159)


--- trunk/Source/WTF/wtf/WorkQueue.h	2021-11-02 15:11:06 UTC (rev 285158)
+++ trunk/Source/WTF/wtf/WorkQueue.h	2021-11-02 15:42:57 UTC (rev 285159)
@@ -48,6 +48,7 @@
     ~WorkQueueBase() override;
 
     WTF_EXPORT_PRIVATE void dispatch(Function<void()>&&) override;
+    WTF_EXPORT_PRIVATE void dispatchWithQOS(Function<void()>&&, QOS);
     WTF_EXPORT_PRIVATE virtual void dispatchAfter(Seconds, Function<void()>&&);
     WTF_EXPORT_PRIVATE virtual void dispatchSync(Function<void()>&&);
 

Modified: trunk/Source/WTF/wtf/cocoa/WorkQueueCocoa.cpp (285158 => 285159)


--- trunk/Source/WTF/wtf/cocoa/WorkQueueCocoa.cpp	2021-11-02 15:11:06 UTC (rev 285158)
+++ trunk/Source/WTF/wtf/cocoa/WorkQueueCocoa.cpp	2021-11-02 15:42:57 UTC (rev 285159)
@@ -54,6 +54,17 @@
     dispatch_async_f(m_dispatchQueue.get(), new DispatchWorkItem { Ref { *this }, WTFMove(function) }, dispatchWorkItem<DispatchWorkItem>);
 }
 
+void WorkQueueBase::dispatchWithQOS(Function<void()>&& function, QOS qos)
+{
+    dispatch_block_t blockWithQOS = dispatch_block_create_with_qos_class(DISPATCH_BLOCK_ENFORCE_QOS_CLASS, Thread::dispatchQOSClass(qos), 0, makeBlockPtr([function = WTFMove(function)] {
+        function();
+    }).get());
+    dispatch_async(m_dispatchQueue.get(), blockWithQOS);
+#if !__has_feature(objc_arc)
+    Block_release(blockWithQOS);
+#endif
+}
+
 void WorkQueueBase::dispatchAfter(Seconds duration, Function<void()>&& function)
 {
     dispatch_after_f(dispatch_time(DISPATCH_TIME_NOW, duration.nanosecondsAs<int64_t>()), m_dispatchQueue.get(), new DispatchWorkItem { Ref { *this },  WTFMove(function) }, dispatchWorkItem<DispatchWorkItem>);

Modified: trunk/Source/WebKit/ChangeLog (285158 => 285159)


--- trunk/Source/WebKit/ChangeLog	2021-11-02 15:11:06 UTC (rev 285158)
+++ trunk/Source/WebKit/ChangeLog	2021-11-02 15:42:57 UTC (rev 285159)
@@ -1,3 +1,28 @@
+2021-11-02  Chris Dumez  <cdu...@apple.com>
+
+        Use higher QoS for WheelEvent and DisplayWasRefreshed IPCs
+        https://bugs.webkit.org/show_bug.cgi?id=232458
+        <rdar://82657744>
+
+        Reviewed by Simon Fraser.
+
+        Use higher QoS for WheelEvent and DisplayWasRefreshed IPCs since those are high priority. The
+        UIProcess's main thread has high UserInteractive QoS but the IPC thread has a lower QoS by default.
+
+        We cannot raise the QoS of the IPC thread without regressing some performance benchmarks since not
+        all IPC is high priority.
+
+        Making this change helps with responsiveness under heavy load scenarios.
+
+        * Platform/IPC/Connection.cpp:
+        (IPC::Connection::sendMessage):
+        * Platform/IPC/Connection.h:
+        (IPC::Connection::send):
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::sendWheelEvent):
+        * UIProcess/mac/DisplayLink.cpp:
+        (WebKit::DisplayLink::notifyObserversDisplayWasRefreshed):
+
 2021-11-02  Zixing Liu  <liushuyu...@gmail.com>
 
         [GTK][WPE] Support setting status code and getting HTTP method in custom URI scheme handlers

Modified: trunk/Source/WebKit/Platform/IPC/Connection.cpp (285158 => 285159)


--- trunk/Source/WebKit/Platform/IPC/Connection.cpp	2021-11-02 15:11:06 UTC (rev 285158)
+++ trunk/Source/WebKit/Platform/IPC/Connection.cpp	2021-11-02 15:42:57 UTC (rev 285159)
@@ -454,7 +454,7 @@
     return encoder;
 }
 
-bool Connection::sendMessage(UniqueRef<Encoder>&& encoder, OptionSet<SendOption> sendOptions)
+bool Connection::sendMessage(UniqueRef<Encoder>&& encoder, OptionSet<SendOption> sendOptions, std::optional<Thread::QOS> qos)
 {
     if (!isValid())
         return false;
@@ -494,9 +494,15 @@
     }
     
     // FIXME: We should add a boolean flag so we don't call this when work has already been scheduled.
-    m_connectionQueue->dispatch([protectedThis = Ref { *this }]() mutable {
+    auto sendOutgoingMessages = [protectedThis = Ref { *this }]() mutable {
         protectedThis->sendOutgoingMessages();
-    });
+    };
+
+    if (qos)
+        m_connectionQueue->dispatchWithQOS(WTFMove(sendOutgoingMessages), *qos);
+    else
+        m_connectionQueue->dispatch(WTFMove(sendOutgoingMessages));
+
     return true;
 }
 

Modified: trunk/Source/WebKit/Platform/IPC/Connection.h (285158 => 285159)


--- trunk/Source/WebKit/Platform/IPC/Connection.h	2021-11-02 15:11:06 UTC (rev 285158)
+++ trunk/Source/WebKit/Platform/IPC/Connection.h	2021-11-02 15:42:57 UTC (rev 285159)
@@ -248,8 +248,8 @@
 
     void postConnectionDidCloseOnConnectionWorkQueue();
     template<typename T, typename C> uint64_t sendWithAsyncReply(T&& message, C&& completionHandler, uint64_t destinationID = 0, OptionSet<SendOption> = { }); // Thread-safe.
-    template<typename T> bool send(T&& message, uint64_t destinationID, OptionSet<SendOption> sendOptions = { }); // Thread-safe.
-    template<typename T> static bool send(UniqueID, T&& message, uint64_t destinationID, OptionSet<SendOption> sendOptions = { }); // Thread-safe.
+    template<typename T> bool send(T&& message, uint64_t destinationID, OptionSet<SendOption> sendOptions = { }, std::optional<Thread::QOS> qos = std::nullopt); // Thread-safe.
+    template<typename T> static bool send(UniqueID, T&& message, uint64_t destinationID, OptionSet<SendOption> sendOptions = { }, std::optional<Thread::QOS> qos = std::nullopt); // Thread-safe.
 
     // Sync senders should check the SendSyncResult for true/false in case they need to know if the result was really received.
     // Sync senders should hold on to the SendSyncResult in case they reference the contents of the reply via DataRefererence / ArrayReference.
@@ -267,9 +267,9 @@
     
     // Thread-safe.
     template<typename T, typename U>
-    bool send(T&& message, ObjectIdentifier<U> destinationID, OptionSet<SendOption> sendOptions = { })
+    bool send(T&& message, ObjectIdentifier<U> destinationID, OptionSet<SendOption> sendOptions = { }, std::optional<Thread::QOS> qos = std::nullopt)
     {
-        return send<T>(WTFMove(message), destinationID.toUInt64(), sendOptions);
+        return send<T>(WTFMove(message), destinationID.toUInt64(), sendOptions, qos);
     }
 
     // Main thread only.
@@ -286,7 +286,7 @@
         return waitForAndDispatchImmediately<T>(destinationID.toUInt64(), timeout, waitForOptions);
     }
 
-    bool sendMessage(UniqueRef<Encoder>&&, OptionSet<SendOption> sendOptions);
+    bool sendMessage(UniqueRef<Encoder>&&, OptionSet<SendOption> sendOptions, std::optional<Thread::QOS> = std::nullopt);
     UniqueRef<Encoder> createSyncMessageEncoder(MessageName, uint64_t destinationID, SyncRequestID&);
     std::unique_ptr<Decoder> sendSyncMessage(SyncRequestID, UniqueRef<Encoder>&&, Timeout, OptionSet<SendSyncOption> sendSyncOptions);
     bool sendSyncReply(UniqueRef<Encoder>&&);
@@ -517,7 +517,7 @@
 };
 
 template<typename T>
-bool Connection::send(T&& message, uint64_t destinationID, OptionSet<SendOption> sendOptions)
+bool Connection::send(T&& message, uint64_t destinationID, OptionSet<SendOption> sendOptions, std::optional<Thread::QOS> qos)
 {
     COMPILE_ASSERT(!T::isSync, AsyncMessageExpected);
 
@@ -524,17 +524,17 @@
     auto encoder = makeUniqueRef<Encoder>(T::name(), destinationID);
     encoder.get() << message.arguments();
     
-    return sendMessage(WTFMove(encoder), sendOptions);
+    return sendMessage(WTFMove(encoder), sendOptions, qos);
 }
 
 template<typename T>
-bool Connection::send(UniqueID connectionID, T&& message, uint64_t destinationID, OptionSet<SendOption> sendOptions)
+bool Connection::send(UniqueID connectionID, T&& message, uint64_t destinationID, OptionSet<SendOption> sendOptions, std::optional<Thread::QOS> qos)
 {
     Locker locker { s_connectionMapLock };
     auto* connection = connectionMap().get(connectionID);
     if (!connection)
         return false;
-    return connection->send(WTFMove(message), destinationID, sendOptions);
+    return connection->send(WTFMove(message), destinationID, sendOptions, qos);
 }
 
 uint64_t nextAsyncReplyHandlerID();

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (285158 => 285159)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2021-11-02 15:11:06 UTC (rev 285158)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2021-11-02 15:42:57 UTC (rev 285159)
@@ -2928,12 +2928,16 @@
     m_wheelEventActivityHysteresis.impulse();
 #endif
 
+    auto* connection = messageSenderConnection();
+    if (!connection)
+        return;
+
     auto rubberBandableEdges = this->rubberBandableEdges();
     if (shouldUseImplicitRubberBandControl()) {
         rubberBandableEdges.setLeft(!m_backForwardList->backItem());
         rubberBandableEdges.setRight(!m_backForwardList->forwardItem());
     }
-    send(Messages::EventDispatcher::WheelEvent(m_webPageID, event, rubberBandableEdges), 0);
+    connection->send(Messages::EventDispatcher::WheelEvent(m_webPageID, event, rubberBandableEdges), 0, { }, Thread::QOS::UserInteractive);
 
     // Manually ping the web process to check for responsiveness since our wheel
     // event will dispatch to a non-main thread, which always responds.

Modified: trunk/Source/WebKit/UIProcess/mac/DisplayLink.cpp (285158 => 285159)


--- trunk/Source/WebKit/UIProcess/mac/DisplayLink.cpp	2021-11-02 15:11:06 UTC (rev 285158)
+++ trunk/Source/WebKit/UIProcess/mac/DisplayLink.cpp	2021-11-02 15:42:57 UTC (rev 285159)
@@ -236,9 +236,9 @@
             << " observers, on background queue " << shouldSendIPCOnBackgroundQueue << " maxFramesPerSecond " << observersMaxFramesPerSecond << " full speed clients " << connectionInfo.fullSpeedUpdatesClientCount << " relevant " << mainThreadWantsUpdate);
 
         if (connectionInfo.fullSpeedUpdatesClientCount) {
-            IPC::Connection::send(connectionID, Messages::EventDispatcher::DisplayWasRefreshed(m_displayID, m_currentUpdate, mainThreadWantsUpdate), 0);
+            IPC::Connection::send(connectionID, Messages::EventDispatcher::DisplayWasRefreshed(m_displayID, m_currentUpdate, mainThreadWantsUpdate), 0, { }, Thread::QOS::UserInteractive);
         } else if (mainThreadWantsUpdate)
-            IPC::Connection::send(connectionID, Messages::WebProcess::DisplayWasRefreshed(m_displayID, m_currentUpdate), 0);
+            IPC::Connection::send(connectionID, Messages::WebProcess::DisplayWasRefreshed(m_displayID, m_currentUpdate), 0, { }, Thread::QOS::UserInteractive);
     }
 
     m_currentUpdate = m_currentUpdate.nextUpdate();
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to