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