Inherit async client CPU priority on connecting/sending requests 27/316127/1
authorKrzysztof Malysa <k.malysa@samsung.com>
Wed, 20 Nov 2024 13:04:58 +0000 (14:04 +0100)
committerKrzysztof Malysa <k.malysa@samsung.com>
Tue, 10 Dec 2024 11:36:15 +0000 (12:36 +0100)
Change-Id: I83587c92d544668d05f12c39c08a5e118416d0c5

src/client-async/logic/Logic.cpp
src/client-async/logic/Logic.h

index 885c8e124b408794eeb3114a5b6a4dac6ec7c7bb..81a91e3bb25039d9fd079a1a84bc58950b039b2d 100644 (file)
  */
 
 #include <cinttypes>
+#include <cpu-boosting.h>
 #include <memory>
+#include <unistd.h>
 
 #include <cache/CapacityCache.h>
 #include <common.h>
 #include <config/PathConfig.h>
+#include <cpu-priority/cpu-priority.h>
 #include <exceptions/Exception.h>
 #include <exceptions/NoMemoryException.h>
 #include <exceptions/UnexpectedErrorException.h>
@@ -49,6 +52,7 @@
 #include <response/CheckResponse.h>
 #include <response/SimpleCheckResponse.h>
 #include <sockets/Socket.h>
+#include <utils/CallInDestructor.h>
 
 #include "Logic.h"
 
@@ -79,6 +83,10 @@ Logic::~Logic() {
     }
 
     m_statusCallback.onDisconnected();
+
+    if (m_requestsInFlightNum > 0 &&
+            resource_clear_cpu_inheritance(gettid(), RESOURCE_CPU_DEST_NAME) != 0)
+        LOGE("resource_clear_cpu_inheritance failed");
 }
 
 void Logic::tryFlushMonitor(void) {
@@ -97,6 +105,19 @@ void Logic::tryFlushMonitor(void) {
     }
 }
 
+void Logic::requestStartAction() {
+    ++m_requestsInFlightNum;
+    LOGD("client-async: requests in flight increased to %zu", m_requestsInFlightNum);
+}
+
+void Logic::requestCompletedOrCancelledAction() {
+    --m_requestsInFlightNum;
+    LOGD("client-async: requests in flight decreased to %zu", m_requestsInFlightNum);
+    if (m_requestsInFlightNum == 0 &&
+            resource_clear_cpu_inheritance(gettid(), RESOURCE_CPU_DEST_NAME) != 0)
+        LOGE("resource_clear_cpu_inheritance failed");
+}
+
 int Logic::checkCache(const std::string &client, const std::string &session,
                       const std::string &user, const std::string &privilege) {
     if (!m_operationPermitted)
@@ -146,6 +167,13 @@ int Logic::createRequest(bool simple, const std::string &client, const std::stri
     if (!m_operationPermitted)
         return CYNARA_API_OPERATION_NOT_ALLOWED;
 
+    requestStartAction();
+    bool requestScheduled = false;
+    auto requestGuard = CallInDestructor{[&] {
+        if (!requestScheduled)
+            requestCompletedOrCancelledAction();
+    }};
+
     if (!ensureConnection())
         return CYNARA_API_SERVICE_NOT_AVAILABLE;
 
@@ -161,6 +189,7 @@ int Logic::createRequest(bool simple, const std::string &client, const std::stri
         m_socketClient.appendRequest(SimpleCheckRequest(key, sequenceNumber));
     else
         m_socketClient.appendRequest(CheckRequest(key, sequenceNumber));
+    requestScheduled = true;
 
     onStatusChange(m_socketClient.getSockFd(), cynara_async_status::CYNARA_STATUS_FOR_RW);
     checkId = static_cast<cynara_check_id>(sequenceNumber);
@@ -223,17 +252,23 @@ void Logic::prepareRequestsToSend(void) {
         if (it->second.cancelled()) {
             m_sequenceContainer.release(it->first);
             it = m_checks.erase(it);
+            requestCompletedOrCancelledAction();
         } else {
             if (it->second.isSimple())
                 m_socketClient.appendRequest(SimpleCheckRequest(it->second.key(), it->first));
             else
                 m_socketClient.appendRequest(CheckRequest(it->second.key(), it->first));
+            // The request is already started, it is just resent now
             ++it;
         }
     }
 }
 
 bool Logic::processOut(void) {
+    // Boost cynara CPU priority before sending requests to it.
+    if (resource_set_cpu_inheritance(gettid(), RESOURCE_CPU_DEST_NAME, 1000) != 0)
+        LOGE("resource_set_cpu_inheritance failed");
+
     switch (m_socketClient.sendToCynara()) {
         case Socket::SendStatus::ALL_DATA_SENT:
             onStatusChange(m_socketClient.getSockFd(),
@@ -259,6 +294,7 @@ Logic::CheckMap::iterator Logic::checkResponseValid(const Response &response) {
 void Logic::releaseRequest(Logic::CheckMap::iterator reqIt) {
     m_sequenceContainer.release(reqIt->first);
     m_checks.erase(reqIt);
+    requestCompletedOrCancelledAction();
 }
 
 void Logic::processCheckResponse(const CheckResponse &checkResponse) {
@@ -369,6 +405,10 @@ bool Logic::ensureConnection(void) {
 }
 
 bool Logic::connect(void) {
+    // Boost cynara CPU priority before connecting to it.
+    if (resource_set_cpu_inheritance(gettid(), RESOURCE_CPU_DEST_NAME, 1000) != 0)
+        LOGE("resource_set_cpu_inheritance failed");
+
     switch (m_socketClient.connect()) {
         case Socket::ConnectionStatus::CONNECTION_SUCCEEDED:
             prepareRequestsToSend();
index 0e55ef953598a14244c25824e2e068e6283690cb..781439843ba17eb7b627d4de9332ed85fbaaea0c 100644 (file)
@@ -84,6 +84,10 @@ private:
     bool m_inAnswerCancelResponseCallback;
     MonitorCache m_monitorCache;
     const bool m_monitoringEnabled;
+    size_t m_requestsInFlightNum = 0;
+
+    void requestStartAction();
+    void requestCompletedOrCancelledAction();
 
     bool checkCacheValid(void);
     int createRequest(bool simple, const std::string &client, const std::string &session,