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