• 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 #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 #include "include/FPS.h"
32 #include "include/sp_task.h"
33 
34 namespace OHOS {
35 namespace SmartPerf {
SmartPerfCommand(std::vector<std::string> argv)36 SmartPerfCommand::SmartPerfCommand(std::vector<std::string> argv)
37 {
38     LOGD("SmartPerfCommand::SmartPerfCommand size(%u)", argv.size());
39     if (argv.size() == oneParam) {
40         EnableWriteLogAndDeleteOldLogFiles();
41         OHOS::SmartPerf::StartUpDelay sd;
42         sd.GetSpTcp();
43         std::string pidStr = sd.GetPidByPkg("SP_daemon");
44         std::string cmdStr = CMD_COMMAND_MAP.at(CmdCommand::TASKSET);
45         std::string result = "";
46         SPUtils::LoadCmd(cmdStr + pidStr, result);
47         daemon(0, 0);
48         CreateSocketThread();
49     }
50     if (argv.size() == twoParam) {
51         auto iterator = COMMAND_HELP_MAP.begin();
52         while (iterator != COMMAND_HELP_MAP.end()) {
53             if (iterator->second.compare(argv[1]) == 0) {
54                 HelpCommand(iterator->first, "");
55                 break;
56             }
57             if (argv[1].find("-editorServer") != std::string::npos) {
58                 WLOGI("############################# Found '-editorServer' argument in argv");
59                 const size_t tokenStartPosition = 14;
60                 std::string token = argv[1].substr(tokenStartPosition, argv[1].length() - tokenStartPosition);
61                 HelpCommand(CommandHelp::EDITORSERVER, token);
62             }
63             ++iterator;
64         }
65     }
66     if (argv.size() >= threeParamMore) {
67         for (int i = 1; i <= static_cast<int>(argv.size()) - 1; i++) {
68             std::string argStr = argv[i];
69             std::string argStr1;
70             if (i < static_cast<int>(argv.size()) - 1) {
71                 argStr1 = argv[i + 1];
72             }
73             if (COMMAND_MAP.count(argStr) > 0) {
74                 HandleCommand(argStr, argStr1);
75             }
76         }
77     }
78     LOGD("SmartPerfCommand::SmartPerfCommand complete");
79 }
HelpCommand(CommandHelp type,std::string token) const80 void SmartPerfCommand::HelpCommand(CommandHelp type, std::string token) const
81 {
82     LOGD("SmartPerfCommand::HelpCommand  type(%d)", type);
83     if (type == CommandHelp::HELP) {
84         std::cout << smartPerfMsg << std::endl;
85     }
86     if (type == CommandHelp::VERSION) {
87         std::cout << "Version: " << SPUtils::GetVersion() << std::endl;
88     }
89     if (type == CommandHelp::SCREEN) {
90         std::string result = SPUtils::GetScreen();
91         std::cout << result << std::endl;
92     }
93     OHOS::SmartPerf::StartUpDelay sd;
94     if (type == CommandHelp::CLEAR) {
95         sd.GetSpClear();
96     }
97     if (type == CommandHelp::SERVER || type == CommandHelp::EDITORSERVER) {
98         sd.ClearOldServer();
99         SPUtils::GetTtyDeviceFd();
100         std::string pidStr = sd.GetPidByPkg("SP_daemon");
101         std::string cmdStr = CMD_COMMAND_MAP.at(CmdCommand::TASKSET);
102         std::string result = "";
103         SPUtils::LoadCmd(cmdStr + pidStr, result);
104         if (type == CommandHelp::SERVER) {
105             daemon(0, 0);
106         } else {
107             EnableWriteLogAndDeleteOldLogFiles();
108             if (token.empty()) {
109                 WLOGE("Error: token is empty when setting TCP token.");
110                 return;
111             } else {
112                 WLOGI("############################# Setting TCP token...");
113                 SPTask::GetInstance().SetTcpToken(token);
114                 WLOGI("############################# EditorServer Socket Create Start, Ready to Start Collector...");
115             }
116         }
117         CreateSocketThread();
118     }
119 }
120 
CreateSocketThread() const121 void SmartPerfCommand::CreateSocketThread() const
122 {
123     InitSomething();
124     SpThreadSocket &udpThreadSocket = SpThreadSocket::GetInstance();
125     SpThreadSocket &udpExThreadSocket = SpThreadSocket::GetInstance();
126     SpThreadSocket &tcpThreadSocket = SpThreadSocket::GetInstance();
127     auto tcpSocket = std::thread([&tcpThreadSocket]() { tcpThreadSocket.Process(ProtoType::TCP); });
128     sleep(1);
129     auto udpSocket = std::thread([&udpThreadSocket]() { udpThreadSocket.Process(ProtoType::UDP); });
130     sleep(1);
131     auto udpexSocket = std::thread([&udpExThreadSocket]() { udpExThreadSocket.Process(ProtoType::UDPEX); });
132     Heartbeat &heartbeat = Heartbeat::GetInstance();
133     heartbeat.UpdatestartTime();
134     std::thread threadHeartbeat([&heartbeat]() {heartbeat.HeartbeatRule(); });
135     threadHeartbeat.detach();
136     tcpSocket.join();
137     udpSocket.join();
138     udpexSocket.join();
139 }
140 
HandleCommand(std::string argStr,const std::string & argStr1)141 void SmartPerfCommand::HandleCommand(std::string argStr, const std::string &argStr1)
142 {
143     LOGD("SmartPerfCommand::HandleCommand  argStr(%s) argStr1(%s)", argStr.c_str(), argStr1.c_str());
144     switch (COMMAND_MAP.at(argStr)) {
145         case CommandType::CT_N:
146             num = SPUtilesTye::StringToSometype<int>(argStr1.c_str());
147             break;
148         case CommandType::CT_PKG:
149             pkgName = argStr1;
150             if (pkgName.length() > 0) {
151                 SpProfilerFactory::SetProfilerPkg(pkgName);
152                 FPS &fps = FPS::GetInstance();
153                 fps.isGameApp = SPUtils::GetIsGameApp(pkgName);
154                 fps.firstDump = true;
155             }
156             break;
157         case CommandType::CT_VIEW:
158             layerName = argStr1;
159             if (layerName.length() > 0) {
160                 SpProfilerFactory::SetProfilerLayer(layerName);
161             }
162             break;
163         case CommandType::CT_OUT:
164             outPathParam = argStr1;
165             if (strcmp(outPathParam.c_str(), "") != 0) {
166                 outPath = outPathParam;
167             }
168             break;
169         case CommandType::CT_C:
170         case CommandType::CT_G:
171         case CommandType::CT_D:
172         case CommandType::CT_F:
173         case CommandType::CT_FDS:
174         case CommandType::CT_T:
175         case CommandType::CT_P:
176         case CommandType::CT_R:
177         case CommandType::CT_NET:
178         case CommandType::CT_TTRACE:
179         case CommandType::CT_THREADS:
180         case CommandType::CT_SNAPSHOT:
181         case CommandType::CT_HW:
182         case CommandType::CT_GC:
183         case CommandType::CT_NAV:
184         case CommandType::CT_AS:
185             configs.push_back(argStr);
186             break;
187         default:
188             HandleCommandContinue(argStr, argStr1);
189             break;
190     }
191 }
192 
HandleCommandContinue(std::string argStr,const std::string & argStr1)193 void SmartPerfCommand::HandleCommandContinue(std::string argStr, const std::string &argStr1)
194 {
195     switch (COMMAND_MAP.at(argStr)) {
196         case CommandType::CT_PID:
197             pid = argStr1;
198             if (pid.length() > 0) {
199                 SpProfilerFactory::SetProfilerPidByPkg(pid);
200             }
201             break;
202         case CommandType::CT_PRINT:
203             configs.push_back(argStr);
204             break;
205         default:
206             std::cout << "other unknown args:" << argStr << std::endl;
207             break;
208     }
209 }
210 
GetItemInfo(std::multimap<std::string,std::string,decltype(SPUtils::Cmp) * > & spMap)211 int SmartPerfCommand::GetItemInfo(std::multimap<std::string, std::string, decltype(SPUtils::Cmp) *> &spMap)
212 {
213     int rc = 0;
214     std::string errInfo;
215     if (!pkgName.empty()) {
216         std::string processId = "";
217         std::string processIds = "";
218         OHOS::SmartPerf::StartUpDelay sp;
219         processId = sp.GetPidByPkg(pkgName, &processIds);
220         LOGD("The cmd pid = %s", processId.c_str());
221         SpProfilerFactory::SetProfilerPidByPkg(processId, processIds);
222     }
223     for (size_t j = 0; j < configs.size(); j++) {
224         std::string curParam = configs[j];
225 
226         if (curParam.find("-gc") != std::string::npos) {
227             continue;
228         }
229 
230         SpProfiler *profiler = SpProfilerFactory::GetCmdProfilerItem(COMMAND_MAP.at(curParam), true);
231         if (profiler != nullptr) {
232             std::map<std::string, std::string> data = profiler->ItemData();
233             spMap.insert(data.cbegin(), data.cend());
234         }
235     }
236 
237     if (!errInfo.empty()) { // GPU Counter init failed
238         printf("%s\n", errInfo.c_str());
239         LOGE("%s", errInfo.c_str());
240         return -1;
241     }
242 
243     return rc;
244 }
245 
SaveGpuCounter() const246 void SmartPerfCommand::SaveGpuCounter() const
247 {
248     std::string outGpuCounterDataPath = "/data/local/tmp";
249     gpuCounter.SaveData(outGpuCounterDataPath);
250     gpuCounter.StopCollect();
251 }
StartGpuCounterCollect(std::string config,bool & flag) const252 void SmartPerfCommand::StartGpuCounterCollect(std::string config, bool &flag) const
253 {
254     if (config.find("-gc") != std::string::npos) {
255         gpuCounter.StartCollect(GpuCounter::GC_START);
256         flag = true;
257     }
258 }
ExecCommand()259 std::string SmartPerfCommand::ExecCommand()
260 {
261     RAM &ram = RAM::GetInstance();
262     ram.SetFirstFlag();
263     int rc = 0;
264     int index = 0;
265     std::vector<SPData> vmap;
266     const long long freq = 1000;
267     num = num + 1;
268     bool gcFlag = false;
269     for (std::string itConfig : configs) {
270         if (itConfig.find("-aischedule") != std::string::npos) {
271             return std::string("Command not support param aischedule");
272         }
273         StartGpuCounterCollect(itConfig, gcFlag);
274     }
275     while (index < num) {
276         std::multimap<std::string, std::string, decltype(SPUtils::Cmp) *> spMap(SPUtils::Cmp);
277         long long lastTime = SPUtils::GetCurTime();
278         spMap.insert(std::pair<std::string, std::string>(std::string("timestamp"), std::to_string(lastTime)));
279         rc = GetItemInfo(spMap);
280         if (rc == -1) {
281             break;
282         }
283         std::map<std::string, std::string> gpuCounterDataMap;
284         gpuCounter.GetGpuRealtimeData(gpuCounterDataMap);
285         spMap.insert(gpuCounterDataMap.begin(), gpuCounterDataMap.end());
286         std::cout << std::endl;
287         PrintMap(spMap, index);
288         std::cout << std::endl;
289         SPData spdata;
290         if (index != 0) {
291             spdata.values.insert(spMap.cbegin(), spMap.cend());
292             vmap.push_back(spdata);
293         }
294         long long nextTime = SPUtils::GetCurTime();
295         long long costTime = nextTime - lastTime;
296         if (costTime < freq) {
297             std::this_thread::sleep_for(std::chrono::milliseconds(freq - costTime));
298         }
299         index++;
300     }
301     if (gcFlag) {
302         SaveGpuCounter();
303     }
304     std::this_thread::sleep_for(std::chrono::milliseconds(freq));
305     SpCsvUtil::WriteCsv(std::string(outPath.c_str()), vmap);
306     return std::string("command exec finished!");
307 }
PrintfExecCommand(const std::map<std::string,std::string> data) const308 void SmartPerfCommand::PrintfExecCommand(const std::map<std::string, std::string> data) const
309 {
310     int i = 0;
311     for (auto a = data.cbegin(); a != data.cend(); ++a) {
312         printf("order:%d %s=%s\n", i++, a->first.c_str(), a->second.c_str());
313     }
314 }
315 
PrintMap(std::multimap<std::string,std::string,decltype(SPUtils::Cmp) * > & spMap,int index) const316 void SmartPerfCommand::PrintMap(std::multimap<std::string, std::string,
317     decltype(SPUtils::Cmp) *> &spMap, int index) const
318 {
319     int i = 0;
320     for (auto iter = spMap.cbegin(); iter != spMap.cend(); ++iter) {
321         if (index != 0) {
322             printf("order:%d %s=%s\n", i++, iter->first.c_str(), iter->second.c_str());
323         }
324     }
325 }
326 
InitSomething()327 void SmartPerfCommand::InitSomething()
328 {
329     std::string cmdResult;
330     std::string stat = CMD_COMMAND_MAP.at(CmdCommand::PROC_STAT);
331     if (SPUtils::LoadCmd(stat, cmdResult)) {
332         LOGE("SmartPerfCommand::InitSomething Privilege escalation!");
333     };
334 }
335 }
336 }
337