1/* 2 * Copyright (c) 2022-2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "thermal_hdf_timer.h" 17 18#include <cerrno> 19#include <fcntl.h> 20#include <linux/netlink.h> 21#include <sys/epoll.h> 22#include <sys/socket.h> 23#include <sys/timerfd.h> 24#include <thread> 25#include <unistd.h> 26 27#include "hdf_base.h" 28#include "string_ex.h" 29#include "thermal_dfx.h" 30#include "thermal_log.h" 31#include "thermal_hdf_utils.h" 32 33namespace OHOS { 34namespace HDI { 35namespace Thermal { 36namespace V1_1 { 37namespace { 38const std::string THERMAL_SIMULATION_TAG = "sim_tz"; 39} 40ThermalHdfTimer::ThermalHdfTimer(const std::shared_ptr<ThermalSimulationNode> &node, 41 const std::shared_ptr<ThermalZoneManager> &thermalZoneMgr) 42{ 43 node_ = node; 44 thermalZoneMgr_ = thermalZoneMgr; 45 reportTime_ = 0; 46} 47 48ThermalHdfTimer::~ThermalHdfTimer() 49{ 50 isRunning_ = false; 51 if (callbackThread_ != nullptr && callbackThread_->joinable()) { 52 callbackThread_->join(); 53 } 54 ThermalDfx::DestroyInstance(); 55} 56 57void ThermalHdfTimer::SetSimluationFlag() 58{ 59 auto baseConfigList = ThermalHdfConfig::GetInstance().GetBaseConfig()->GetBaseItem(); 60 if (baseConfigList.empty()) { 61 THERMAL_HILOGE(COMP_HDI, "baseConfigList is empty"); 62 return; 63 } 64 auto baseIter = std::find(baseConfigList.begin(), baseConfigList.end(), THERMAL_SIMULATION_TAG); 65 if (baseIter != baseConfigList.end()) { 66 StrToInt(TrimStr(baseIter->value), isSim_); 67 THERMAL_HILOGI(COMP_HDI, "isSim value:%{public}d", isSim_); 68 } else { 69 THERMAL_HILOGI(COMP_HDI, "not found"); 70 } 71} 72 73void ThermalHdfTimer::SetSimFlag(int32_t flag) 74{ 75 isSim_ = flag; 76} 77 78int32_t ThermalHdfTimer::GetSimluationFlag() 79{ 80 return isSim_; 81} 82 83void ThermalHdfTimer::TimerProviderCallback() 84{ 85 reportTime_ = reportTime_ + 1; 86 ReportThermalData(); 87 ResetCount(); 88 return; 89} 90 91void ThermalHdfTimer::LoopingThreadEntry() 92{ 93 int32_t dfxInterval = static_cast<int32_t>(ThermalDfx::GetInstance().GetInterval()); 94 int32_t gcd = ThermalHdfUtils::GetMaxCommonDivisor(thermalZoneMgr_->GetMaxCd(), dfxInterval); 95 if (dfxInterval == 0 || gcd == 0) { 96 THERMAL_HILOGE(COMP_HDI, "LoopingThreadEntry error"); 97 return; 98 } 99 int32_t loopingTimes = 0; 100 while (isRunning_) { 101 std::this_thread::sleep_for(std::chrono::milliseconds(gcd)); 102 loopingTimes++; 103 int32_t dfxTask = loopingTimes % (dfxInterval / gcd); 104 int32_t reportTask = loopingTimes % (thermalZoneMgr_->GetMaxCd() / gcd); 105 if (dfxTask == 0) { 106 ThermalDfx::GetInstance().DoWork(); 107 } 108 if (reportTask == 0) { 109 TimerProviderCallback(); 110 } 111 // both dfxTask and reportTask execute, and reset loopingTimes 112 if ((dfxTask == 0) && (reportTask == 0)) { 113 loopingTimes = 0; 114 } 115 } 116} 117 118void ThermalHdfTimer::Run() 119{ 120 callbackThread_ = std::make_unique<std::thread>([this] { this->LoopingThreadEntry(); }); 121} 122 123void ThermalHdfTimer::StartThread() 124{ 125 Run(); 126} 127 128int32_t ThermalHdfTimer::Init() 129{ 130 ThermalDfx::GetInstance().Init(); 131 StartThread(); 132 return HDF_SUCCESS; 133} 134 135void ThermalHdfTimer::ReportThermalData() 136{ 137 thermalZoneMgr_->ReportThermalZoneData(reportTime_); 138} 139 140void ThermalHdfTimer::ResetCount() 141{ 142 if (reportTime_ == thermalZoneMgr_->GetMaxReportTime()) { 143 THERMAL_HILOGD(COMP_HDI, "reportTime:%{public}d", reportTime_); 144 reportTime_ = 0; 145 } 146} 147} // V1_1 148} // Thermal 149} // HDI 150} // OHOS 151