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
33 namespace OHOS {
34 namespace HDI {
35 namespace Thermal {
36 namespace V1_1 {
37 namespace {
38 const std::string THERMAL_SIMULATION_TAG = "sim_tz";
39 }
ThermalHdfTimer(const std::shared_ptr<ThermalSimulationNode> & node,const std::shared_ptr<ThermalZoneManager> & thermalZoneMgr)40 ThermalHdfTimer::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
~ThermalHdfTimer()48 ThermalHdfTimer::~ThermalHdfTimer()
49 {
50 isRunning_ = false;
51 if (callbackThread_ != nullptr && callbackThread_->joinable()) {
52 callbackThread_->join();
53 }
54 ThermalDfx::DestroyInstance();
55 }
56
SetSimluationFlag()57 void 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
SetSimFlag(int32_t flag)73 void ThermalHdfTimer::SetSimFlag(int32_t flag)
74 {
75 isSim_ = flag;
76 }
77
GetSimluationFlag()78 int32_t ThermalHdfTimer::GetSimluationFlag()
79 {
80 return isSim_;
81 }
82
TimerProviderCallback()83 void ThermalHdfTimer::TimerProviderCallback()
84 {
85 reportTime_ = reportTime_ + 1;
86 ReportThermalData();
87 ResetCount();
88 return;
89 }
90
LoopingThreadEntry()91 void 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
Run()118 void ThermalHdfTimer::Run()
119 {
120 callbackThread_ = std::make_unique<std::thread>([this] { this->LoopingThreadEntry(); });
121 }
122
StartThread()123 void ThermalHdfTimer::StartThread()
124 {
125 Run();
126 }
127
Init()128 int32_t ThermalHdfTimer::Init()
129 {
130 ThermalDfx::GetInstance().Init();
131 StartThread();
132 return HDF_SUCCESS;
133 }
134
ReportThermalData()135 void ThermalHdfTimer::ReportThermalData()
136 {
137 thermalZoneMgr_->ReportThermalZoneData(reportTime_);
138 }
139
ResetCount()140 void 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