diff --git a/cgroup_sched/framework/sched_controller/cgroup_adjuster.cpp b/cgroup_sched/framework/sched_controller/cgroup_adjuster.cpp index 9ccf8e0163eaa32bb0ac1a9f0f1726212409b52e..ce39fa892cdf142af802d5248d3da1eeae723d72 100644 --- a/cgroup_sched/framework/sched_controller/cgroup_adjuster.cpp +++ b/cgroup_sched/framework/sched_controller/cgroup_adjuster.cpp @@ -76,8 +76,11 @@ void CgroupAdjuster::AdjustProcessGroup(Application &app, ProcessRecord &pr, Adj for (const auto &iter : app.GetPidsMap()) { const auto &procRecord = iter.second; if (procRecord && procRecord->isRenderProcess_) { - CGS_LOGI("%{public}s for %{public}d, source : %{public}d", __func__, procRecord->GetPid(), source); + CGS_LOGI("%{public}s for %{public}d, source : %{public}d for render process", + __func__, procRecord->GetPid(), source); procRecord->setSchedGroup_ = mainProcRecord->curSchedGroup_; + ResSchedUtils::GetInstance().ReportArbitrationResult(app, *(procRecord.get()), + AdjustSource::ADJS_SELF_RENDER_THREAD); ApplyProcessGroup(app, *procRecord); } } diff --git a/cgroup_sched/framework/sched_controller/cgroup_event_handler.cpp b/cgroup_sched/framework/sched_controller/cgroup_event_handler.cpp index 12fb1f72313c5402b7145e2b0d4d46a27f960e7d..3cef518d244d879421bf594c0e9595073b140d58 100644 --- a/cgroup_sched/framework/sched_controller/cgroup_event_handler.cpp +++ b/cgroup_sched/framework/sched_controller/cgroup_event_handler.cpp @@ -34,6 +34,7 @@ namespace { constexpr uint32_t EVENT_ID_REG_BGTASK_OBSERVER = 2; constexpr uint32_t DELAYED_RETRY_REGISTER_DURATION = 100; constexpr uint32_t MAX_RETRY_TIMES = 100; + constexpr uint32_t MAX_SPAN_SERIAL = 99; const std::string MMI_SERVICE_NAME = "mmi_service"; } @@ -523,6 +524,90 @@ void CgroupEventHandler::HandleReportRenderThread(uint32_t resType, int64_t valu AdjustSource::ADJS_REPORT_RENDER_THREAD); } +void CgroupEventHandler::HandleReportKeyThread(uint32_t resType, int64_t value, const nlohmann::json& payload) +{ + int32_t uid = 0; + int32_t pid = 0; + int32_t keyTid = 0; + int32_t role = 0; + + if (!supervisor_) { + CGS_LOGE("%{public}s : supervisor nullptr!", __func__); + return; + } + + if (!ParseValue(uid, "uid", payload) || !ParseValue(pid, "pid", payload) || + !ParseValue(keyTid, "tid", payload) || !ParseValue(role, "role", payload)) { + return; + } + + if (uid <= 0 || pid <= 0) { + return; + } + + auto app = supervisor_->GetAppRecordNonNull(uid); + auto procRecord = app->GetProcessRecordNonNull(pid); + if (value == ResType::ReportChangeStatus::CREATE) { + procRecord->keyThreadRoleMap_.emplace(keyTid, role); + } else { + procRecord->keyThreadRoleMap_.erase(keyTid); + } + + // if role of thread is important display, adjust it + auto mainProcRecord = app->GetMainProcessRecord(); + if (!mainProcRecord) { + return; + } + CgroupAdjuster::GetInstance().AdjustProcessGroup(*(app.get()), *(mainProcRecord.get()), + AdjustSource::ADJS_REPORT_IMPORTANT_DISPLAY_THREAD); +} + +void CgroupEventHandler::HandleReportWindowState(uint32_t resType, int64_t value, const nlohmann::json& payload) +{ + int32_t uid = 0; + int32_t pid = 0; + int32_t windowId = -1; + int32_t state = 0; + int32_t nowSerialNum = -1; + + if (!supervisor_) { + CGS_LOGE("%{public}s : supervisor nullptr!", __func__); + return; + } + + if (!ParseValue(uid, "uid", payload) || !ParseValue(pid, "pid", payload) || + !ParseValue(windowId, "windowId", payload) || !ParseValue(state, "state", payload) || + !ParseValue(nowSerialNum, "serialNum", payload)) { + return; + } + if (uid <= 0 || pid <= 0) { + return; + } + + auto app = supervisor_->GetAppRecordNonNull(uid); + auto procRecord = app->GetProcessRecordNonNull(pid); + CGS_LOGD("%{public}s : render process name: %{public}s, uid: %{public}d, pid: %{public}d, state: %{public}d", + __func__, app->GetName().c_str(), uid, pid, state); + if (nowSerialNum <= procRecord->serialNum_ && (procRecord->serialNum_ - nowSerialNum <= MAX_SPAN_SERIAL)) { + return; + } + procRecord->serialNum_ = nowSerialNum; + + if (state == ResType::WindowStates::ACTIVE) { + procRecord->linkedWindowId_ = windowId; + procRecord->isActive_ = true; + } else { + procRecord->linkedWindowId_ = -1; + procRecord->isActive_ = false; + } + auto mainProcRecord = app->GetMainProcessRecord(); + if (!mainProcRecord) { + return; + } + CgroupAdjuster::GetInstance().AdjustProcessGroup(*(app.get()), *(mainProcRecord.get()), + AdjustSource::ADJS_REPORT_WINDOW_STATE_CHANGED); +} + bool CgroupEventHandler::ParsePayload(int32_t& uid, int32_t& pid, int32_t& tid, int64_t value, const nlohmann::json& payload) { @@ -536,5 +621,15 @@ bool CgroupEventHandler::ParsePayload(int32_t& uid, int32_t& pid, int32_t& tid, tid = static_cast(value); return true; } + +bool CgroupEventHandler::ParseValue(int32_t& value, const char* name, + const nlohmann::json& payload) +{ + if (payload.contains(name) && payload.at(name).is_string()) { + value = atoi(payload[name].get().c_str()); + return true; + } + return false; +} } // namespace ResourceSchedule } // namespace OHOS diff --git a/cgroup_sched/framework/sched_controller/include/cgroup_adjuster.h b/cgroup_sched/framework/sched_controller/include/cgroup_adjuster.h index 08901dfd32403de8ad00ee2bd87e8e4c2d5cd077..fb84d0f57b39ed571a433825bebbc663fc76bccb 100644 --- a/cgroup_sched/framework/sched_controller/include/cgroup_adjuster.h +++ b/cgroup_sched/framework/sched_controller/include/cgroup_adjuster.h @@ -37,6 +37,9 @@ enum class AdjustSource { ADJS_WINDOW_VISIBILITY_CHANGED, ADJS_REPORT_RENDER_THREAD, ADJS_REPORT_MMI_SERVICE_THREAD, + ADJS_REPORT_IMPORTANT_DISPLAY_THREAD, + ADJS_SELF_RENDER_THREAD, + ADJS_REPORT_WINDOW_STATE_CHANGED, ADJS_END }; diff --git a/cgroup_sched/framework/sched_controller/include/cgroup_event_handler.h b/cgroup_sched/framework/sched_controller/include/cgroup_event_handler.h index c5f43f98ac344ddc49693cc1eebd55bb742347cf..ea099af665c0ec54acdd6a1ad21f5a7da19e3b3e 100644 --- a/cgroup_sched/framework/sched_controller/include/cgroup_event_handler.h +++ b/cgroup_sched/framework/sched_controller/include/cgroup_event_handler.h @@ -57,9 +57,12 @@ public: WindowType windowType, int32_t pid, int32_t uid); void HandleReportMMIProcess(uint32_t resType, int64_t value, const nlohmann::json& payload); void HandleReportRenderThread(uint32_t resType, int64_t value, const nlohmann::json& payload); + void HandleReportKeyThread(uint32_t resType, int64_t value, const nlohmann::json& payload); + void HandleReportWindowState(uint32_t resType, int64_t value, const nlohmann::json& payload); private: bool ParsePayload(int32_t& uid, int32_t& pid, int32_t& tid, int64_t value, const nlohmann::json& payload); + bool ParseValue(int32_t& value, const char* name, const nlohmann::json& payload); std::shared_ptr supervisor_; }; } // namespace ResourceSchedule diff --git a/cgroup_sched/framework/sched_controller/include/supervisor.h b/cgroup_sched/framework/sched_controller/include/supervisor.h index 4a2f3b039effa00432f4923cf489ef03d408eb0b..7dc7faa72ca6f4c5ffeec9a0e27bd8c644bf153e 100644 --- a/cgroup_sched/framework/sched_controller/include/supervisor.h +++ b/cgroup_sched/framework/sched_controller/include/supervisor.h @@ -21,6 +21,8 @@ #include #include #include +#include +#include #include "sched_policy.h" @@ -79,6 +81,7 @@ public: bool HasAbility(uintptr_t token) const; bool HasServiceExtension() const; bool IsVisible() const; + std::set GetKeyTidSetByRole(int64_t role); inline pid_t GetPid() const { @@ -95,15 +98,19 @@ public: SchedPolicy setSchedGroup_ = SP_UPPER_LIMIT; bool isRenderProcess_ = false; bool runningTransientTask_ = false; + bool isActive_ {false}; bool isExtensionProcess_ = false; uint32_t continuousTaskFlag_ = 0; int32_t renderTid_ = 0; int32_t maliTid_ = 0; + int32_t linkedWindowId_ {-1}; + int32_t serialNum_ {-1}; int32_t extensionType_ = -1; std::vector> abilities_; std::vector> windows_; + std::map keyThreadRoleMap_ {}; // items in keyThreadMap_ is (tid, role) private: uid_t uid_; pid_t pid_; diff --git a/cgroup_sched/framework/sched_controller/sched_controller.cpp b/cgroup_sched/framework/sched_controller/sched_controller.cpp index 9652e3fdc7bc988ea9c3d89081864ead6f3bdf61..90515c8a8b9ef07f7cac8c3605ca488f90b3af25 100644 --- a/cgroup_sched/framework/sched_controller/sched_controller.cpp +++ b/cgroup_sched/framework/sched_controller/sched_controller.cpp @@ -131,6 +131,14 @@ void SchedController::DispatchResource(uint32_t resType, int64_t value, const nl handler->HandleReportRenderThread(resType, value, payload); break; } + case ResType::RES_TYPE_REPORT_KEY_THREAD: { + handler->HandleReportKeyThread(resType, value, payload); + break; + } + case ResType::RES_TYPE_REPORT_WINDOW_STATE: { + handler->HandleReportWindowState(resType, value, payload); + break; + } default: { break; } diff --git a/cgroup_sched/framework/sched_controller/supervisor.cpp b/cgroup_sched/framework/sched_controller/supervisor.cpp index 179998944b1c27bb95041124b9abab50edd2ec16..7dcb9e5aa02a709454961fdc13e60580c13a13b3 100644 --- a/cgroup_sched/framework/sched_controller/supervisor.cpp +++ b/cgroup_sched/framework/sched_controller/supervisor.cpp @@ -91,6 +91,18 @@ bool ProcessRecord::IsVisible() const }); } +std::set ProcessRecord::GetKeyTidSetByRole(int64_t role) +{ + std::set tids {}; + for (const auto [tid, tidRole] : keyThreadRoleMap_) { + if (tidRole != role) { + continue; + } + tids.insert(tid); + } + return tids; +} + std::shared_ptr Application::AddProcessRecord(std::shared_ptr pr) { if (pr) { diff --git a/ressched/test/unittest/src/res_sched_mgr_test.cpp b/ressched/test/unittest/src/res_sched_mgr_test.cpp index 1200218b9d5c13bbf62b8b93b3ebd411c9fe8664..44f1b9415f2a613f24dd8d912fe5e234c7778e90 100644 --- a/ressched/test/unittest/src/res_sched_mgr_test.cpp +++ b/ressched/test/unittest/src/res_sched_mgr_test.cpp @@ -46,7 +46,7 @@ HWTEST_F(ResSchedMgrTest, Init001, TestSize.Level1) } /** - * @tc.name: Init ressched ReportData 002 + * @tc.name: Init ressched ReportData 001 * @tc.desc: Verify if ReportData is success * @tc.type: FUNC * @tc.require: issueI5WWV3 @@ -57,10 +57,40 @@ HWTEST_F(ResSchedMgrTest, ReportData001, TestSize.Level1) nlohmann::json payload; ResSchedMgr::GetInstance().ReportData(0, 0, payload); EXPECT_TRUE(ResSchedMgr::GetInstance().killProcess_ != nullptr); - + ResSchedMgr::GetInstance().DispatchResourceInner(0, 0, payload); } +/** + * @tc.name: Init ressched ReportData 002 + * @tc.desc: Verify if ReportData is success + * @tc.type: FUNC + * @tc.require: issueI897BM + */ +HWTEST_F(ResSchedMgrTest, ReportData002, TestSize.Level1) +{ + nlohmann::json payload; + ResSchedMgr::GetInstance().ReportData(ResType::RES_TYPE_REPORT_KEY_THREAD, 0, payload); + EXPECT_TRUE(ResSchedMgr::GetInstance().killProcess_ != nullptr); + + ResSchedMgr::GetInstance().DispatchResourceInner(ResType::RES_TYPE_REPORT_KEY_THREAD, 0, payload); +} + +/** + * @tc.name: Init ressched ReportData 003 + * @tc.desc: Verify if ReportData is success + * @tc.type: FUNC + * @tc.require: issueI897BM + */ +HWTEST_F(ResSchedMgrTest, ReportData003, TestSize.Level1) +{ + nlohmann::json payload; + ResSchedMgr::GetInstance().ReportData(ResType::RES_TYPE_REPORT_WINDOW_STATE, 0, payload); + EXPECT_TRUE(ResSchedMgr::GetInstance().killProcess_ != nullptr); + + ResSchedMgr::GetInstance().DispatchResourceInner(ResType::RES_TYPE_REPORT_WINDOW_STATE, 0, payload); +} + /** * @tc.name: Init ressched KillProcess 001 * @tc.desc: Verify if killProcess is success