From 7c674c793351869eb73c335e170e122b2ea455cc Mon Sep 17 00:00:00 2001 From: peterhuangyu Date: Wed, 31 Jan 2024 11:45:16 +0800 Subject: [PATCH] Measurement of Main Thread Message Processing Time Signed-off-by: peterhuangyu --- frameworks/eventhandler/src/event_handler.cpp | 28 ++++++++++ frameworks/eventhandler/src/event_runner.cpp | 32 ++++++++++++ interfaces/inner_api/event_handler.h | 7 +++ interfaces/inner_api/event_runner.h | 52 +++++++++++++++++++ 4 files changed, 119 insertions(+) diff --git a/frameworks/eventhandler/src/event_handler.cpp b/frameworks/eventhandler/src/event_handler.cpp index fb71d7a..28ab74d 100644 --- a/frameworks/eventhandler/src/event_handler.cpp +++ b/frameworks/eventhandler/src/event_handler.cpp @@ -311,6 +311,21 @@ void EventHandler::DistributeTimeAction(const InnerEvent::Pointer &event, InnerE #endif // HAS_HICHECKER_NATIVE_PART } +void EventHandler::DistributeTimeoutHandler(const InnerEvent::TimePoint& beginTime) +{ + int64_t distributeTimeout = EventRunner::GetMainEventRunner()->GetTimeout(); + if (distributeTimeout > 0) { + InnerEvent::TimePoint endTime = InnerEvent::Clock::now(); + if ((endTime - std::chrono::milliseconds(distributeTimeout)) > beginTime && + EventRunner::distributeCallback_) { + HILOGI("AppMainThread Callback."); + auto diff = endTime - beginTime; + int64_t durationTime = std::chrono::duration_cast(diff).count(); + EventRunner::distributeCallback_(durationTime); + } + } +} + void EventHandler::DistributeEvent(const InnerEvent::Pointer &event) { if (!event) { @@ -338,6 +353,14 @@ void EventHandler::DistributeEvent(const InnerEvent::Pointer &event) DeliveryTimeAction(event, nowStart); HILOGD("EventName is %{public}s, eventId is %{public}s .", GetEventName(event).c_str(), (event->GetEventUniqueId()).c_str()); + + std::string eventName = GetEventName(event); + InnerEvent::TimePoint beginTime; + bool isAppMainThread = EventRunner::IsAppMainThread(); + if (EventRunner::distributeBegin_ && isAppMainThread) { + beginTime = EventRunner::distributeBegin_(eventName); + } + if (event->HasTask()) { // Call task callback directly if contains a task. (event->GetTaskCallback())(); @@ -346,6 +369,11 @@ void EventHandler::DistributeEvent(const InnerEvent::Pointer &event) ProcessEvent(event); } + if (EventRunner::distributeBegin_ && EventRunner::distributeEnd_ && isAppMainThread) { + EventRunner::distributeEnd_(eventName, beginTime); + DistributeTimeoutHandler(beginTime); + } + DistributeTimeAction(event, nowStart); if (allowTraceOutPut) { diff --git a/frameworks/eventhandler/src/event_runner.cpp b/frameworks/eventhandler/src/event_runner.cpp index 87a8b7b..e40d106 100644 --- a/frameworks/eventhandler/src/event_runner.cpp +++ b/frameworks/eventhandler/src/event_runner.cpp @@ -38,6 +38,7 @@ namespace AppExecFwk { namespace { const char *g_crashEmptyDumpInfo = "Current Event Caller is empty. Nothing to dump"; const int CRASH_BUF_MIN_LEN = 2; +constexpr int64_t MIN_APP_UID = 20000; thread_local static Caller g_currentEventCaller = {}; thread_local static std::string g_currentEventName = {}; @@ -485,6 +486,9 @@ ThreadCollector::Avatar ThreadCollector::avatar_; } // unnamed namespace std::shared_ptr EventRunner::mainRunner_; +EventRunner::DistributeBeginTime EventRunner::distributeBegin_ = nullptr; +EventRunner::DistributeEndTime EventRunner::distributeEnd_ = nullptr; +EventRunner::CallbackTime EventRunner::distributeCallback_ = nullptr; std::shared_ptr EventRunner::Create(bool inNewThread) { @@ -672,5 +676,33 @@ std::shared_ptr EventRunner::GetMainEventRunner() return mainRunner_; } + +bool EventRunner::IsAppMainThread() +{ + static int pid = -1; + static int uid = -1; + + if (pid == -1) { + pid = getpid(); + } + if (uid == -1) { + uid = getuid(); + } + if (pid == gettid() && uid >= MIN_APP_UID) { + return true; + } + return false; +} + +void EventRunner::SetMainLooperWatcher(const DistributeBeginTime begin, + const DistributeEndTime end) +{ + if (begin != nullptr && end != nullptr) { + distributeBegin_ = begin; + distributeEnd_ = end; + } else { + HILOGE("SetMainLooperWatcher Error, invaild parameter"); + } +} } // namespace AppExecFwk } // namespace OHOS diff --git a/interfaces/inner_api/event_handler.h b/interfaces/inner_api/event_handler.h index 641c06b..977f996 100644 --- a/interfaces/inner_api/event_handler.h +++ b/interfaces/inner_api/event_handler.h @@ -919,6 +919,13 @@ public: return eventRunner_; } + /** + * Distribute time out handler. + * + * @param beginTime Dotting before distribution. + */ + void DistributeTimeoutHandler(const InnerEvent::TimePoint& beginTime); + /** * Distribute the event. * diff --git a/interfaces/inner_api/event_runner.h b/interfaces/inner_api/event_runner.h index 6679b95..e863f28 100644 --- a/interfaces/inner_api/event_runner.h +++ b/interfaces/inner_api/event_runner.h @@ -21,6 +21,7 @@ #include "event_queue.h" #include "dumper.h" #include "logger.h" +#include "inner_event.h" namespace OHOS { namespace AppExecFwk { @@ -32,6 +33,13 @@ public: ~EventRunner(); DISALLOW_COPY_AND_MOVE(EventRunner); + using DistributeBeginTime = std::function; + using DistributeEndTime = std::function; + using CallbackTime = std::function; + static DistributeBeginTime distributeBegin_; + static DistributeEndTime distributeEnd_; + static CallbackTime distributeCallback_; + /** * Create new 'EventRunner'. * @@ -192,6 +200,49 @@ public: return distributeTimeout_; } + /** + * Set the main thread timeout period. + * + * @param distributeTimeout the distribution standard expiration time. + */ + void SetTimeout(int64_t distributeTimeout) + { + timeout_ = distributeTimeout; + } + + /** + * Set distribute time out callback. + * + * @param callback Distribute Time out callback. + */ + void SetTimeoutCallback(CallbackTime callback) + { + distributeCallback_ = callback; + } + + /** + * Get the execution standard timeout period. + * + * @return the distribution standard expiration time. + */ + int64_t GetTimeout() const + { + return timeout_; + } + + /** + * Check if the current application is the main thread. + */ + static bool IsAppMainThread(); + + /** + * Set app main thread watcher. + * + * @param callback Distribute Start Time callback. + * @param callback Distribute End Time callback. + */ + void SetMainLooperWatcher(const DistributeBeginTime begin, const DistributeEndTime end); + /** * Obtains the EventRunner for the main thread of the application. * @@ -217,6 +268,7 @@ private: int64_t deliveryTimeout_ = 0; int64_t distributeTimeout_ = 0; + int64_t timeout_ = 0; bool deposit_{true}; std::atomic running_{false}; std::shared_ptr queue_; -- Gitee