• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 "include/CPU.h"
17 #include <sstream>
18 #include <cstdio>
19 #include <unistd.h>
20 #include <cstring>
21 #include <string>
22 #include <iostream>
23 #include <climits>
24 #include "securec.h"
25 #include "include/sp_utils.h"
26 #include "cpu_collector.h"
27 #include "collect_result.h"
28 #include "include/startup_delay.h"
29 #include "include/sp_log.h"
30 
31 using namespace OHOS::HiviewDFX;
32 using namespace OHOS::HiviewDFX::UCollectUtil;
33 using namespace OHOS::HiviewDFX::UCollect;
34 
35 namespace OHOS {
36 namespace SmartPerf {
ItemData()37 std::map<std::string, std::string> CPU::ItemData()
38 {
39     usleep(twenty * thousand);
40     std::map<std::string, std::string> result;
41     std::vector<CpuFreqs> cpuFreqInfo = GetCpuFreq();
42     for (size_t i = 0; i < cpuFreqInfo.size(); i++) {
43         std::string cpuFreqStr = std::to_string(cpuFreqInfo[i].curFreq);
44         std::string cpuId = std::to_string(cpuFreqInfo[i].cpuId);
45         result["cpu" + cpuId + "Frequency"] = cpuFreqStr;
46     }
47     std::vector<CpuUsageInfos> workLoads = GetCpuUsage();
48     const size_t oneHundred = 100;
49     if (workLoads.empty()) {
50         return result;
51     }
52     for (size_t i = 0; i < workLoads.size(); i++) {
53         std::string cpuIdStr = workLoads[i].cpuId;
54         std::string userUsageStr = std::to_string(workLoads[i].userUsage * oneHundred);
55         std::string niceUsageStr = std::to_string(workLoads[i].niceUsage * oneHundred);
56         std::string systemUsageStr = std::to_string(workLoads[i].systemUsage * oneHundred);
57         std::string idleUsageStr = std::to_string(workLoads[i].idleUsage * oneHundred);
58         std::string ioWaitUsageStr = std::to_string(workLoads[i].ioWaitUsage * oneHundred);
59         std::string irqUsageStr = std::to_string(workLoads[i].irqUsage * oneHundred);
60         std::string softIrqUsageStr = std::to_string(workLoads[i].softIrqUsage * oneHundred);
61         std::string totalUsageStr = std::to_string((workLoads[i].userUsage + workLoads[i].niceUsage +
62             workLoads[i].systemUsage + workLoads[i].ioWaitUsage + workLoads[i].irqUsage + workLoads[i].softIrqUsage) *
63             oneHundred);
64         if (cpuIdStr == cpustr) {
65             cpuIdStr = totalcpu;
66         }
67         result[cpuIdStr + "userUsage"] = userUsageStr;
68         result[cpuIdStr + "niceUsage"] = niceUsageStr;
69         result[cpuIdStr + "systemUsage"] = systemUsageStr;
70         result[cpuIdStr + "idleUsage"] = idleUsageStr;
71         result[cpuIdStr + "ioWaitUsage"] = ioWaitUsageStr;
72         result[cpuIdStr + "irqUsage"] = irqUsageStr;
73         result[cpuIdStr + "softIrqUsage"] = softIrqUsageStr;
74         result[cpuIdStr + "Usage"] = totalUsageStr;
75     }
76     if ((!packageName.empty() || !processId.empty())) {
77         std::map<std::string, std::string> processCpuInfo = CPU::GetSysProcessCpuLoad();
78         if (!processCpuInfo.empty()) {
79             for (const auto& item : processCpuInfo) {
80                 result.insert(item);
81             }
82         }
83     }
84 
85     LOGD("CPU::ItemData map size(%u)", result.size());
86     return result;
87 }
88 
SetPackageName(const std::string & pName)89 void CPU::SetPackageName(const std::string &pName)
90 {
91     packageName = pName;
92     LOGD("CPU SetPackageName name(%s)", pName.c_str());
93 }
94 
SetProcessId(const std::string & pid)95 void CPU::SetProcessId(const std::string &pid)
96 {
97     LOGD("CPU SetProcessId (%s)", pid.c_str());
98     processId.clear();
99     SPUtils::StrSplit(pid, " ", processId);
100 }
101 
GetCpuFreq()102 std::vector<CpuFreqs> CPU::GetCpuFreq()
103 {
104     OHOS::SmartPerf::CpuFreqs cpuFreqs;
105     std::vector<CpuFreqs> cpuFrequency;
106     std::shared_ptr<CpuCollector> collector = CpuCollector::Create();
107     CollectResult<std::vector<CpuFreq>> result = collector->CollectCpuFrequency();
108     std::vector<CpuFreq> &cpufreq = result.data;
109     for (size_t i = 0; i < cpufreq.size(); i++) {
110         cpuFreqs.cpuId = cpufreq[i].cpuId;
111         cpuFreqs.curFreq = cpufreq[i].curFreq;
112         cpuFrequency.push_back(cpuFreqs);
113         LOGD("cpuFreqs.cpuId: %s, cpuFreqs.curFreq: %s",
114             std::to_string(cpufreq[i].cpuId).c_str(), std::to_string(cpufreq[i].curFreq).c_str());
115     }
116     return cpuFrequency;
117 }
118 
GetCpuUsage()119 std::vector<CpuUsageInfos> CPU::GetCpuUsage()
120 {
121     OHOS::SmartPerf::CpuUsageInfos cpuUsageInfos;
122     std::vector<CpuUsageInfos> workload;
123     std::shared_ptr<CpuCollector> collector = CpuCollector::Create();
124     CollectResult<SysCpuUsage> result = collector->CollectSysCpuUsage(true);
125     SysCpuUsage &sysCpuUsage = result.data;
126     if (sysCpuUsage.cpuInfos.empty()) {
127         return workload;
128     }
129     for (auto &cpuInfo : sysCpuUsage.cpuInfos) {
130         cpuUsageInfos.cpuId = cpuInfo.cpuId;
131         cpuUsageInfos.userUsage = cpuInfo.userUsage;
132         cpuUsageInfos.niceUsage = cpuInfo.niceUsage;
133         cpuUsageInfos.systemUsage = cpuInfo.systemUsage;
134         cpuUsageInfos.idleUsage = cpuInfo.idleUsage;
135         cpuUsageInfos.ioWaitUsage = cpuInfo.ioWaitUsage;
136         cpuUsageInfos.irqUsage = cpuInfo.irqUsage;
137         cpuUsageInfos.softIrqUsage = cpuInfo.softIrqUsage;
138         workload.push_back(cpuUsageInfos);
139         LOGD("UsageCpuId: %s, userUsage: %s, niceUsage: %s, systemUsage: %s",
140             "idleUsage: %s, ioWaitUsage: %s, irqUsage: %s, softIrqUsage: %s",
141             cpuInfo.cpuId.c_str(), std::to_string(cpuInfo.userUsage).c_str(),
142             std::to_string(cpuInfo.niceUsage).c_str(), std::to_string(cpuInfo.systemUsage).c_str(),
143             std::to_string(cpuInfo.idleUsage).c_str(), std::to_string(cpuInfo.ioWaitUsage).c_str(),
144             std::to_string(cpuInfo.irqUsage).c_str(), std::to_string(cpuInfo.softIrqUsage).c_str());
145     }
146     return workload;
147 }
148 
GetSysProcessCpuLoad() const149 std::map<std::string, std::string> CPU::GetSysProcessCpuLoad() const
150 {
151     std::map<std::string, std::string> processCpuInfo;
152     const size_t oneHundred = 100;
153     if (!processId.empty()) {
154         std::shared_ptr<CpuCollector> collector = CpuCollector::Create();
155         for (size_t i = 0; i < processId.size(); i++) {
156             int32_t procId = 0;
157             procId = SPUtilesTye::StringToSometype<int32_t>(processId[i]);
158             auto collectResult = collector->CollectProcessCpuStatInfo(procId, true);
159             auto data = collectResult.data;
160             if (i == 0) {
161                 processCpuInfo["ProcId"] = std::to_string(data.pid);
162                 processCpuInfo["ProcAppName"] = data.procName;
163                 processCpuInfo["ProcCpuLoad"] = std::to_string(data.cpuLoad * oneHundred);
164                 processCpuInfo["ProcCpuUsage"] = std::to_string(data.cpuUsage * oneHundred);
165                 processCpuInfo["ProcUCpuUsage"] = std::to_string(data.uCpuUsage * oneHundred);
166                 processCpuInfo["ProcSCpuUsage"] = std::to_string(data.sCpuUsage * oneHundred);
167                 GetSysChildProcessCpuLoad(processId.size(), processCpuInfo);
168             } else {
169                 processCpuInfo["ChildProcId"].append(std::to_string(data.pid)).append("|");
170                 processCpuInfo["ChildProcCpuLoad"].append(std::to_string(data.cpuLoad * oneHundred)).append("|");
171                 processCpuInfo["ChildProcCpuUsage"].append(std::to_string(data.cpuUsage * oneHundred)).append("|");
172                 processCpuInfo["ChildProcUCpuUsage"].append(std::to_string(data.uCpuUsage * oneHundred)).append("|");
173                 processCpuInfo["ChildProcSCpuUsage"].append(std::to_string(data.sCpuUsage * oneHundred)).append("|");
174             }
175             LOGD("ProcId: %s, ProcAppName: %s, ProcCpuLoad: %s, ProcCpuUsage: %s, ProcUCpuUsage: %s, ProcSCpuUsage: %s",
176                 std::to_string(data.pid).c_str(), data.procName.c_str(), std::to_string(data.cpuLoad).c_str(),
177                 std::to_string(data.cpuUsage).c_str(), std::to_string(data.uCpuUsage).c_str(),
178                 std::to_string(data.sCpuUsage).c_str());
179         }
180     } else {
181         processCpuInfo["ProcId"] = "NA";
182         processCpuInfo["ProcAppName"] = packageName;
183         processCpuInfo["ProcCpuLoad"] = "NA";
184         processCpuInfo["ProcCpuUsage"] = "NA";
185         processCpuInfo["ProcUCpuUsage"] = "NA";
186         processCpuInfo["ProcSCpuUsage"] = "NA";
187         processCpuInfo["ChildProcId"] = "NA";
188         processCpuInfo["ChildProcCpuLoad"] = "NA";
189         processCpuInfo["ChildProcCpuUsage"] = "NA";
190         processCpuInfo["ChildProcUCpuUsage"] = "NA";
191         processCpuInfo["ChildProcSCpuUsage"] = "NA";
192     }
193     GetSysProcessCpuLoadContinue(processCpuInfo);
194     return processCpuInfo;
195 }
196 
GetSysProcessCpuLoadContinue(std::map<std::string,std::string> & processCpuInfo) const197 void CPU::GetSysProcessCpuLoadContinue(std::map<std::string, std::string> &processCpuInfo) const
198 {
199     if (processCpuInfo.find("ProcAppName") != processCpuInfo.end() && processCpuInfo["ProcAppName"].empty()) {
200         processCpuInfo["ProcId"] = "0";
201         processCpuInfo["ProcAppName"] = packageName;
202         processCpuInfo["ProcCpuLoad"] = "0";
203         processCpuInfo["ProcCpuUsage"] = "0";
204         processCpuInfo["ProcUCpuUsage"] = "0";
205         processCpuInfo["ProcSCpuUsage"] = "0";
206         processCpuInfo["ChildProcId"] = "0";
207         processCpuInfo["ChildProcCpuLoad"] = "0";
208         processCpuInfo["ChildProcCpuUsage"] = "0";
209         processCpuInfo["ChildProcUCpuUsage"] = "0";
210         processCpuInfo["ChildProcSCpuUsage"] = "0";
211     }
212 }
213 
GetSysChildProcessCpuLoad(size_t processIdSize,std::map<std::string,std::string> & processCpuInfo) const214 void CPU::GetSysChildProcessCpuLoad(size_t processIdSize, std::map<std::string, std::string> &processCpuInfo) const
215 {
216     if (processIdSize == 1) {
217         processCpuInfo["ChildProcId"] = "NA";
218         processCpuInfo["ChildProcCpuLoad"] = "NA";
219         processCpuInfo["ChildProcCpuUsage"] = "NA";
220         processCpuInfo["ChildProcUCpuUsage"] = "NA";
221         processCpuInfo["ChildProcSCpuUsage"] = "NA";
222     }
223 }
224 }
225 }
226