/* * Copyright (c) 2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "session/host/include/ws_ffrt_helper.h" #include #include #include #include #include "c/executor_task.h" #include "ffrt.h" #include "ffrt_inner.h" #include "hitrace_meter.h" #include "window_manager_hilog.h" namespace OHOS::Rosen { namespace { constexpr int32_t FFRT_USER_INTERACTIVE_MAX_THREAD_NUM = 5; constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WSFFRTHelper"}; const std::unordered_map FFRT_QOS_MAP = { { TaskQos::INHERIT, ffrt_qos_inherit }, { TaskQos::BACKGROUND, ffrt_qos_background }, { TaskQos::UTILITY, ffrt_qos_utility }, { TaskQos::DEFAULT, ffrt_qos_default }, { TaskQos::USER_INITIATED, ffrt_qos_user_initiated }, { TaskQos::DEADLINE_REQUEST, ffrt_qos_deadline_request }, { TaskQos::USER_INTERACTIVE, ffrt_qos_user_interactive }, }; } class TaskHandleMap { public: void SaveTask(const std::string& taskName, ffrt::task_handle handle) { std::unique_lock lock(mutex_); taskMap_[taskName] = std::move(handle); } void RemoveTask(const std::string& taskName) { std::unique_lock lock(mutex_); if (auto iter = taskMap_.find(taskName); iter != taskMap_.end()) { if (iter->second != nullptr) { auto ret = ffrt::skip(iter->second); if (ret != 0) { WLOGI("Failed to cancel task, taskName = %{public}s, retcode = %{public}d", taskName.c_str(), ret); } } taskMap_.erase(iter); } else { WLOGI("Task is not existed, taskName = %{public}s", taskName.c_str()); } } bool IsTaskExisted(const std::string& taskName) { std::shared_lock lock(mutex_); auto iter = taskMap_.find(taskName); return iter != taskMap_.end() && iter->second != nullptr; } std::size_t CountTask() { std::shared_lock lock(mutex_); return taskMap_.size(); } private: std::unordered_map taskMap_; std::shared_mutex mutex_; }; WSFFRTHelper::WSFFRTHelper() : taskHandleMap_(std::make_unique()) { static bool firstInit = [] { int ret = ffrt_set_cpu_worker_max_num(ffrt_qos_user_interactive, FFRT_USER_INTERACTIVE_MAX_THREAD_NUM); WLOGI("FFRT user interactive qos max thread number = %{public}d, retcode = %{public}d", FFRT_USER_INTERACTIVE_MAX_THREAD_NUM, ret); return true; }(); } WSFFRTHelper::~WSFFRTHelper() = default; void WSFFRTHelper::SubmitTask(std::function&& task, const std::string& taskName, uint64_t delayTime, TaskQos qos) { auto localTask = [task = std::move(task), taskName]() { HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "f:%s", taskName.c_str()); task(); }; if (delayTime == 0 && ffrt_get_cur_task() != nullptr) { localTask(); return; } ffrt::task_handle handle = ffrt::submit_h(std::move(localTask), {}, {}, ffrt::task_attr().delay(delayTime). qos(FFRT_QOS_MAP.at(qos))); if (handle == nullptr) { WLOGE("Failed to post task, taskName = %{public}s", taskName.c_str()); return; } taskHandleMap_->SaveTask(taskName, std::move(handle)); } void WSFFRTHelper::CancelTask(const std::string& taskName) { taskHandleMap_->RemoveTask(taskName); } bool WSFFRTHelper::IsTaskExisted(const std::string& taskName) const { return taskHandleMap_->IsTaskExisted(taskName); } std::size_t WSFFRTHelper::CountTask() const { return taskHandleMap_->CountTask(); } } // namespace OHOS::Rosen