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