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 32namespace OHOS { 33namespace SmartPerf { 34SmartPerfCommand::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} 72void 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 102void 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} 121void 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 167int 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 200void SmartPerfCommand::SaveGpuCounter() const 201{ 202 std::string outGpuCounterDataPath = "/data/local/tmp"; 203 gpuCounter.SaveData(outGpuCounterDataPath); 204 gpuCounter.StopCollect(); 205} 206 207std::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} 258void 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 266void 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 277void 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