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 #include <cstdio>
16 #include <thread>
17 #include <cstring>
18 #include <iterator>
19 #include "unistd.h"
20 #include "include/heartbeat.h"
21 #include "include/sp_utils.h"
22 #include "include/sp_csv_util.h"
23 #include "include/sp_profiler_factory.h"
24 #include "include/sp_thread_socket.h"
25 #include "include/startup_delay.h"
26 #include "include/ByTrace.h"
27 #include "include/smartperf_command.h"
28 #include "include/sp_log.h"
29 #include "include/RAM.h"
30 #include "include/common.h"
31
32 namespace OHOS {
33 namespace SmartPerf {
SmartPerfCommand(std::vector<std::string> argv)34 SmartPerfCommand::SmartPerfCommand(std::vector<std::string> argv)
35 {
36 LOGI("SmartPerfCommand::SmartPerfCommand size(%u)", argv.size());
37 if (argv.size() == oneParam) {
38 OHOS::SmartPerf::StartUpDelay sd;
39 sd.GetSpTcp();
40 std::string pidStr = sd.GetPidByPkg("SP_daemon");
41 std::string cmdStr = CMD_COMMAND_MAP.at(CmdCommand::TASKSET);
42 std::string result = "";
43 SPUtils::LoadCmd(cmdStr + pidStr, result);
44 daemon(0, 0);
45 CreateSocketThread();
46 }
47 if (argv.size() == twoParam) {
48 auto iterator = COMMAND_HELP_MAP.begin();
49 while (iterator != COMMAND_HELP_MAP.end()) {
50 if (iterator->second.compare(argv[1]) == 0) {
51 HelpCommand(iterator->first);
52 break;
53 }
54 ++iterator;
55 }
56 }
57 if (argv.size() >= threeParamMore) {
58 for (int i = 1; i <= static_cast<int>(argv.size()) - 1; i++) {
59 std::string argStr = argv[i];
60 std::string argStr1;
61 if (i < static_cast<int>(argv.size()) - 1) {
62 argStr1 = argv[i + 1];
63 }
64 if (COMMAND_MAP.count(argStr) > 0) {
65 HandleCommand(argStr, argStr1);
66 }
67 }
68 }
69
70 LOGI("SmartPerfCommand::SmartPerfCommand complete");
71 }
HelpCommand(CommandHelp type) const72 void SmartPerfCommand::HelpCommand(CommandHelp type) const
73 {
74 LOGI("SmartPerfCommand::HelpCommand type(%d)", type);
75 if (type == CommandHelp::HELP) {
76 std::cout << smartPerfMsg << std::endl;
77 }
78 if (type == CommandHelp::VERSION) {
79 std::cout << "Version: " << smartPerfVersion << std::endl;
80 }
81 if (type == CommandHelp::SCREEN) {
82 std::string result = SPUtils::GetScreen();
83 std::cout << result << std::endl;
84 }
85 OHOS::SmartPerf::StartUpDelay sd;
86 if (type == CommandHelp::CLEAR) {
87 sd.GetSpClear();
88 }
89 if (type == CommandHelp::SERVER || type == CommandHelp::EDITORSERVER) {
90 sd.ClearOldServer();
91 std::string pidStr = sd.GetPidByPkg("SP_daemon");
92 std::string cmdStr = CMD_COMMAND_MAP.at(CmdCommand::TASKSET);
93 std::string result = "";
94 SPUtils::LoadCmd(cmdStr + pidStr, result);
95 if (type == CommandHelp::SERVER) {
96 daemon(0, 0);
97 }
98 CreateSocketThread();
99 }
100 }
101
CreateSocketThread() const102 void SmartPerfCommand::CreateSocketThread() const
103 {
104 InitSomething();
105 SpThreadSocket udpThreadSocket;
106 SpThreadSocket udpExThreadSocket;
107 SpThreadSocket tcpThreadSocket;
108 auto tcpSocket = std::thread([&tcpThreadSocket]() { tcpThreadSocket.Process(ProtoType::TCP); });
109 sleep(1);
110 auto udpSocket = std::thread([&udpThreadSocket]() { udpThreadSocket.Process(ProtoType::UDP); });
111 sleep(1);
112 auto udpexSocket = std::thread([&udpExThreadSocket]() { udpExThreadSocket.Process(ProtoType::UDPEX); });
113 Heartbeat &heartbeat = Heartbeat::GetInstance();
114 heartbeat.UpdatestartTime();
115 std::thread threadHeartbeat([&heartbeat]() {heartbeat.HeartbeatRule(); });
116 threadHeartbeat.detach();
117 tcpSocket.join();
118 udpSocket.join();
119 udpexSocket.join();
120 }
HandleCommand(std::string argStr, const std::string &argStr1)121 void SmartPerfCommand::HandleCommand(std::string argStr, const std::string &argStr1)
122 {
123 LOGI("SmartPerfCommand::HandleCommand argStr(%s) argStr1(%s)", argStr.c_str(), argStr1.c_str());
124 switch (COMMAND_MAP.at(argStr)) {
125 case CommandType::CT_N:
126 num = atoi(argStr1.c_str());
127 break;
128 case CommandType::CT_PKG:
129 pkgName = argStr1;
130 if (pkgName.length() > 0) {
131 SpProfilerFactory::SetProfilerPkg(pkgName);
132 }
133 break;
134 case CommandType::CT_VIEW:
135 layerName = argStr1;
136 if (layerName.length() > 0) {
137 SpProfilerFactory::SetProfilerLayer(layerName);
138 }
139 break;
140 case CommandType::CT_OUT:
141 outPathParam = argStr1;
142 if (strcmp(outPathParam.c_str(), "") != 0) {
143 outPath = outPathParam;
144 }
145 break;
146 case CommandType::CT_C:
147 case CommandType::CT_G:
148 case CommandType::CT_D:
149 case CommandType::CT_F:
150 case CommandType::CT_T:
151 case CommandType::CT_P:
152 case CommandType::CT_R:
153 case CommandType::CT_NET:
154 case CommandType::CT_TTRACE:
155 case CommandType::CT_SNAPSHOT:
156 case CommandType::CT_HW:
157 case CommandType::CT_GC:
158 case CommandType::CT_NAV:
159 configs.push_back(argStr);
160 break;
161 default:
162 std::cout << "other unknown args:" << argStr << std::endl;
163 break;
164 }
165 }
166
GetItemInfo(std::multimap<std::string, std::string, decltype(SPUtils::Cmp) *> &spMap)167 int SmartPerfCommand::GetItemInfo(std::multimap<std::string, std::string, decltype(SPUtils::Cmp) *> &spMap)
168 {
169 int rc = 0;
170 std::string errInfo;
171 if (!pkgName.empty()) {
172 std::string processId = "";
173 OHOS::SmartPerf::StartUpDelay sp;
174 processId = sp.GetPidByPkg(pkgName);
175 SpProfilerFactory::SetProfilerPidByPkg(processId);
176 }
177 for (size_t j = 0; j < configs.size(); j++) {
178 std::string curParam = configs[j];
179
180 if (curParam.find("-gc") != std::string::npos) {
181 continue;
182 }
183
184 SpProfiler *profiler = SpProfilerFactory::GetCmdProfilerItem(COMMAND_MAP.at(curParam), true);
185 if (profiler != nullptr) {
186 std::map<std::string, std::string> data = profiler->ItemData();
187 spMap.insert(data.cbegin(), data.cend());
188 }
189 }
190
191 if (!errInfo.empty()) { // GPU Counter init failed
192 printf("%s\n", errInfo.c_str());
193 LOGE("%s", errInfo.c_str());
194 return -1;
195 }
196
197 return rc;
198 }
199
SaveGpuCounter() const200 void SmartPerfCommand::SaveGpuCounter() const
201 {
202 std::string outGpuCounterDataPath = "/data/local/tmp";
203 gpuCounter.SaveData(outGpuCounterDataPath);
204 gpuCounter.StopCollect();
205 }
206
ExecCommand()207 std::string SmartPerfCommand::ExecCommand()
208 {
209 RAM &ram = RAM::GetInstance();
210 ram.SetFirstFlag();
211 int rc = 0;
212 int index = 0;
213 std::vector<SPData> vmap;
214 const long long freq = 1000;
215 num = num + 1;
216 bool gcFlag = false;
217 for (std::string itConfig : configs) {
218 if (itConfig.find("-gc") != std::string::npos) {
219 gpuCounter.StartCollect(GpuCounter::GC_START);
220 gcFlag = true;
221 }
222 }
223 while (index < num) {
224 std::multimap<std::string, std::string, decltype(SPUtils::Cmp) *> spMap(SPUtils::Cmp);
225 long long lastTime = SPUtils::GetCurTime();
226 spMap.insert(std::pair<std::string, std::string>(std::string("timestamp"), std::to_string(lastTime)));
227 rc = GetItemInfo(spMap);
228 if (rc == -1) {
229 break;
230 }
231 std::map<std::string, std::string> gpuCounterDataMap;
232 gpuCounter.GetGpuRealtimeData(gpuCounterDataMap);
233 spMap.insert(gpuCounterDataMap.begin(), gpuCounterDataMap.end());
234 std::cout << std::endl;
235 PrintMap(spMap, index);
236 std::cout << std::endl;
237 SPData spdata;
238 if (index != 0) {
239 spdata.values.insert(spMap.cbegin(), spMap.cend());
240 vmap.push_back(spdata);
241 }
242 long long nextTime = SPUtils::GetCurTime();
243 long long costTime = nextTime - lastTime;
244 if (costTime < freq) {
245 std::this_thread::sleep_for(std::chrono::milliseconds(freq - costTime));
246 }
247 index++;
248 }
249 if (gcFlag) {
250 SaveGpuCounter();
251 }
252 std::this_thread::sleep_for(std::chrono::milliseconds(freq));
253 LOGI("SmartPerfCommand::WriteCsv start");
254 SpCsvUtil::WriteCsv(std::string(outPath.c_str()), vmap);
255 LOGI("SmartPerfCommand::WriteCsv finish");
256 return std::string("command exec finished!");
257 }
PrintfExecCommand(const std::map<std::string, std::string> data) const258 void SmartPerfCommand::PrintfExecCommand(const std::map<std::string, std::string> data) const
259 {
260 int i = 0;
261 for (auto a = data.cbegin(); a != data.cend(); ++a) {
262 printf("order:%d %s=%s\n", i++, a->first.c_str(), a->second.c_str());
263 }
264 }
265
PrintMap(std::multimap<std::string, std::string, decltype(SPUtils::Cmp) *> &spMap, int index) const266 void SmartPerfCommand::PrintMap(std::multimap<std::string, std::string,
267 decltype(SPUtils::Cmp) *> &spMap, int index) const
268 {
269 int i = 0;
270 for (auto iter = spMap.cbegin(); iter != spMap.cend(); ++iter) {
271 if (index != 0) {
272 printf("order:%d %s=%s\n", i++, iter->first.c_str(), iter->second.c_str());
273 }
274 }
275 }
276
InitSomething()277 void SmartPerfCommand::InitSomething()
278 {
279 std::string cmdResult;
280 std::string stat = CMD_COMMAND_MAP.at(CmdCommand::PROC_STAT);
281 if (SPUtils::LoadCmd(stat, cmdResult)) {
282 LOGI("SmartPerfCommand::InitSomething Privilege escalation!");
283 };
284 }
285 }
286 }
287