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 std::map<std::string, std::string> result;
40 std::vector<CpuFreqs> cpuFreqInfo = GetCpuFreq();
41 for (size_t i = 0; i < cpuFreqInfo.size(); i++) {
42 std::string cpuFreqStr = std::to_string(cpuFreqInfo[i].curFreq);
43 std::string cpuId = std::to_string(cpuFreqInfo[i].cpuId);
44 result["cpu" + cpuId + "Frequency"] = cpuFreqStr;
45 }
46 std::vector<CpuUsageInfos> workLoads = GetCpuUsage();
47 const size_t oneHundred = 100;
48 if (workLoads.empty()) {
49 return result;
50 }
51 for (size_t i = 1; i < workLoads.size(); i++) {
52 std::string cpuIdStr = workLoads[i].cpuId;
53 std::string userUsageStr = std::to_string(workLoads[i].userUsage * oneHundred);
54 std::string niceUsageStr = std::to_string(workLoads[i].niceUsage * oneHundred);
55 std::string systemUsageStr = std::to_string(workLoads[i].systemUsage * oneHundred);
56 std::string idleUsageStr = std::to_string(workLoads[i].idleUsage * oneHundred);
57 std::string ioWaitUsageStr = std::to_string(workLoads[i].ioWaitUsage * oneHundred);
58 std::string irqUsageStr = std::to_string(workLoads[i].irqUsage * oneHundred);
59 std::string softIrqUsageStr = std::to_string(workLoads[i].softIrqUsage * oneHundred);
60 std::string totalUsageStr = std::to_string((workLoads[i].userUsage + workLoads[i].niceUsage +
61 workLoads[i].systemUsage + workLoads[i].ioWaitUsage + workLoads[i].irqUsage + workLoads[i].softIrqUsage) *
62 oneHundred);
63 result[cpuIdStr + "userUsage"] = userUsageStr;
64 result[cpuIdStr + "niceUsage"] = niceUsageStr;
65 result[cpuIdStr + "systemUsage"] = systemUsageStr;
66 result[cpuIdStr + "idleUsage"] = idleUsageStr;
67 result[cpuIdStr + "ioWaitUsage"] = ioWaitUsageStr;
68 result[cpuIdStr + "irqUsage"] = irqUsageStr;
69 result[cpuIdStr + "softIrqUsage"] = softIrqUsageStr;
70 result[cpuIdStr + "Usage"] = totalUsageStr;
71 }
72 if (packageName.length() > 0) {
73 std::map<std::string, std::string> processCpuInfo = CPU::GetSysProcessCpuLoad();
74 if (!processCpuInfo.empty()) {
75 for (auto it = processCpuInfo.begin(); it != processCpuInfo.end(); ++it) {
76 result.insert(*it);
77 }
78 }
79 }
80
81 LOGI("CPU::ItemData map size(%u)", result.size());
82 return result;
83 }
84
SetPackageName(const std::string & pName)85 void CPU::SetPackageName(const std::string &pName)
86 {
87 packageName = pName;
88 LOGI("CPU SetPackageName name(%s)", pName.c_str());
89 }
90
SetProcessId(const std::string & pid)91 void CPU::SetProcessId(const std::string &pid)
92 {
93 processId = pid;
94 }
95
GetCpuFreq()96 std::vector<CpuFreqs> CPU::GetCpuFreq()
97 {
98 OHOS::SmartPerf::CpuFreqs cpuFreqs;
99 std::vector<CpuFreqs> cpuFrequency;
100 std::shared_ptr<CpuCollector> collector = CpuCollector::Create();
101 CollectResult<std::vector<CpuFreq>> result = collector->CollectCpuFrequency();
102 std::vector<CpuFreq> &cpufreq = result.data;
103 for (size_t i = 0; i < cpufreq.size(); i++) {
104 cpuFreqs.cpuId = cpufreq[i].cpuId;
105 cpuFreqs.curFreq = cpufreq[i].curFreq;
106 cpuFrequency.push_back(cpuFreqs);
107 LOGI("cpuFreqs.cpuId: %s", std::to_string(cpufreq[i].cpuId).c_str());
108 LOGI("cpuFreqs.curFreq: %s", std::to_string(cpufreq[i].curFreq).c_str());
109 }
110 return cpuFrequency;
111 }
112
GetCpuUsage()113 std::vector<CpuUsageInfos> CPU::GetCpuUsage()
114 {
115 OHOS::SmartPerf::CpuUsageInfos cpuUsageInfos;
116 std::vector<CpuUsageInfos> workload;
117 std::shared_ptr<CpuCollector> collector = CpuCollector::Create();
118 CollectResult<SysCpuUsage> result = collector->CollectSysCpuUsage(true);
119 SysCpuUsage &sysCpuUsage = result.data;
120 if (sysCpuUsage.cpuInfos.empty()) {
121 return workload;
122 }
123 for (auto &cpuInfo : sysCpuUsage.cpuInfos) {
124 cpuUsageInfos.cpuId = cpuInfo.cpuId;
125 cpuUsageInfos.userUsage = cpuInfo.userUsage;
126 cpuUsageInfos.niceUsage = cpuInfo.niceUsage;
127 cpuUsageInfos.systemUsage = cpuInfo.systemUsage;
128 cpuUsageInfos.idleUsage = cpuInfo.idleUsage;
129 cpuUsageInfos.ioWaitUsage = cpuInfo.ioWaitUsage;
130 cpuUsageInfos.irqUsage = cpuInfo.irqUsage;
131 cpuUsageInfos.softIrqUsage = cpuInfo.softIrqUsage;
132 workload.push_back(cpuUsageInfos);
133 LOGI("UsageCpuId: %s", cpuInfo.cpuId.c_str());
134 LOGI("userUsage: %s", std::to_string(cpuInfo.userUsage).c_str());
135 LOGI("niceUsage: %s", std::to_string(cpuInfo.niceUsage).c_str());
136 LOGI("systemUsage: %s", std::to_string(cpuInfo.systemUsage).c_str());
137 LOGI("idleUsage: %s", std::to_string(cpuInfo.idleUsage).c_str());
138 LOGI("ioWaitUsage: %s", std::to_string(cpuInfo.ioWaitUsage).c_str());
139 LOGI("irqUsage: %s", std::to_string(cpuInfo.irqUsage).c_str());
140 LOGI("softIrqUsage: %s", std::to_string(cpuInfo.softIrqUsage).c_str());
141 }
142 return workload;
143 }
144
GetSysProcessCpuLoad() const145 std::map<std::string, std::string> CPU::GetSysProcessCpuLoad() const
146 {
147 std::map<std::string, std::string> processCpuInfo;
148 const size_t oneHundred = 100;
149 if (processId.length() > 0) {
150 int32_t procId = 0;
151 procId = std::stoi(processId);
152 std::shared_ptr<CpuCollector> collector = CpuCollector::Create();
153 auto collectResult = collector->CollectProcessCpuStatInfo(procId, true);
154 auto data = collectResult.data;
155 processCpuInfo["ProcId"] = std::to_string(data.pid);
156 processCpuInfo["ProcAppName"] = data.procName;
157 processCpuInfo["ProcCpuLoad"] = std::to_string(data.cpuLoad * oneHundred);
158 processCpuInfo["ProcCpuUsage"] = std::to_string(data.cpuUsage * oneHundred);
159 processCpuInfo["ProcUCpuUsage"] = std::to_string(data.uCpuUsage * oneHundred);
160 processCpuInfo["ProcSCpuUsage"] = std::to_string(data.sCpuUsage * oneHundred);
161 LOGI("ProcId: %s", std::to_string(data.pid).c_str());
162 LOGI("ProcAppName: %s", data.procName.c_str());
163 LOGI("ProcCpuLoad: %s", std::to_string(data.cpuLoad).c_str());
164 LOGI("ProcCpuUsage: %s", std::to_string(data.cpuUsage).c_str());
165 LOGI("ProcUCpuUsage: %s", std::to_string(data.uCpuUsage).c_str());
166 LOGI("ProcSCpuUsage: %s", std::to_string(data.sCpuUsage).c_str());
167 } else {
168 processCpuInfo["ProcId"] = "NA";
169 processCpuInfo["ProcAppName"] = packageName;
170 processCpuInfo["ProcCpuLoad"] = "NA";
171 processCpuInfo["ProcCpuUsage"] = "NA";
172 processCpuInfo["ProcUCpuUsage"] = "NA";
173 processCpuInfo["ProcSCpuUsage"] = "NA";
174 }
175 if (processCpuInfo.find("ProcAppName") != processCpuInfo.end() && processCpuInfo["ProcAppName"].empty()) {
176 processCpuInfo["ProcId"] = "0";
177 processCpuInfo["ProcAppName"] = packageName;
178 processCpuInfo["ProcCpuLoad"] = "0";
179 processCpuInfo["ProcCpuUsage"] = "0";
180 processCpuInfo["ProcUCpuUsage"] = "0";
181 processCpuInfo["ProcSCpuUsage"] = "0";
182 }
183 return processCpuInfo;
184 }
185 }
186 }
187