From 3951e394f2741bfb7912b71144f084282ba48451 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=89=9B=E5=9B=BD=E4=BA=AE?= Date: Sat, 2 Aug 2025 15:17:23 +0800 Subject: [PATCH] add smartperf factory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 牛国亮 --- .../utils/src/sp_profiler_factory.cpp | 268 +++++++++++++++++ .../utils/src/startup_delay.cpp | 279 ++++++++++++++++++ 2 files changed, 547 insertions(+) create mode 100644 smartperf_device/device_command/utils/src/sp_profiler_factory.cpp create mode 100644 smartperf_device/device_command/utils/src/startup_delay.cpp diff --git a/smartperf_device/device_command/utils/src/sp_profiler_factory.cpp b/smartperf_device/device_command/utils/src/sp_profiler_factory.cpp new file mode 100644 index 000000000..0ec6a8b9c --- /dev/null +++ b/smartperf_device/device_command/utils/src/sp_profiler_factory.cpp @@ -0,0 +1,268 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include "include/AI_schedule.h" +#include "include/CPU.h" +#include "include/DDR.h" +#include "include/GameEvent.h" +#include "include/GetLog.h" +#include "include/GPU.h" +#include "include/FPS.h" +#include "include/RAM.h" +#include "include/Network.h" +#include "include/Power.h" +#include "include/Temperature.h" +#include "include/ByTrace.h" +#include "include/sp_utils.h" +#include "include/sp_profiler_factory.h" +#include "include/Capture.h" +#include "include/navigation.h" +#include "include/sp_log.h" +#include "include/FileDescriptor.h" +#include "include/Threads.h" +#include "include/GpuCounter.h" +#include "effective.h" +#include "include/cpu_info.h" +#include "include/lock_frequency.h" +#include "include/hiperf.h" +#include "include/sdk_data_recv.h" + +namespace OHOS { +namespace SmartPerf { +SpProfiler *SpProfilerFactory::GetProfilerItem(MessageType messageType) +{ + SpProfiler* profiler = nullptr; + switch (messageType) { + case MessageType::GET_CPU_FREQ_LOAD: + profiler = &CPU::GetInstance(); + break; + case MessageType::GET_FPS_AND_JITTERS: + case MessageType::GET_CUR_FPS: + profiler = &FPS::GetInstance(); + break; + case MessageType::GET_GPU_FREQ: + case MessageType::GET_GPU_LOAD: + profiler = &GPU::GetInstance(); + break; + case MessageType::GET_DDR_FREQ: + profiler = &DDR::GetInstance(); + break; + case MessageType::GET_RAM_INFO: + profiler = &RAM::GetInstance(); + break; + case MessageType::GET_LOG: + profiler = &GetLog::GetInstance(); + break; + case MessageType::GET_PROCESS_THREADS: + profiler = &Threads::GetInstance(); + break; + case MessageType::GET_PROCESS_FDS: + profiler = &FileDescriptor::GetInstance(); + break; + default: + break; + } + if (profiler == nullptr) { + profiler = GetProfilerItemContinue(messageType); + } + return profiler; +} +SpProfiler *SpProfilerFactory::GetProfilerItemContinue(MessageType messageType) +{ + SpProfiler* profiler = nullptr; + switch (messageType) { + case MessageType::GET_TEMPERATURE: + profiler = &Temperature::GetInstance(); + break; + case MessageType::GET_POWER: + profiler = &Power::GetInstance(); + break; + case MessageType::CATCH_TRACE_CONFIG: + FPS::GetInstance().SetTraceCatch(); + break; + case MessageType::GET_CAPTURE: + Capture::GetInstance().SocketMessage(); + profiler = &Capture::GetInstance(); + break; + case MessageType::CATCH_NETWORK_TRAFFIC: + case MessageType::GET_NETWORK_TRAFFIC: + profiler = &Network::GetInstance(); + break; + default: + break; + } + return profiler; +} + +void SpProfilerFactory::SetProfilerPkg(const std::string &pkg) +{ + LOGD("SpProfilerFactory setPKG:%s", pkg.c_str()); + FPS::GetInstance().SetPackageName(pkg); + RAM::GetInstance().SetPackageName(pkg); + CPU::GetInstance().SetPackageName(pkg); + Threads::GetInstance().SetPackageName(pkg); + FileDescriptor::GetInstance().SetPackageName(pkg); +} + +void SpProfilerFactory::SetProfilerPidByPkg(std::string &pid, std::string pids) +{ + LOGD("SpProfilerFactory setPID:%s", pid.c_str()); + FPS::GetInstance().SetProcessId(pid); + Hiperf::GetInstance().SetProcessId(pid); + RAM::GetInstance().SetProcessId(pids.empty() ? pid : pids); + CPU::GetInstance().SetProcessId(pids.empty() ? pid : pids); + Navigation::GetInstance().SetProcessId(pid); + AISchedule::GetInstance().SetProcessId(pid); + Threads::GetInstance().SetProcessId(pids.empty() ? pid : pids); + FileDescriptor::GetInstance().SetProcessId(pids.empty() ? pid : pids); + CPUInfo::GetInstance().SetPids(pids.empty() ? pid : pids); +} + +void SpProfilerFactory::SetByTrace(const std::string& message) +{ + std::vector values; + std::string delimiter = "||"; + std::string delim = "="; + SPUtils::StrSplit(message, delimiter, values); + int mSum = 0; + int mInterval = 0; + long long mThreshold = 0; + int lowFps = 0; + for (std::string& vItem : values) { + std::vector vItems; + SPUtils::StrSplit(vItem, delim, vItems); + if (vItems[0] == "traceSum") { + mSum = SPUtilesTye::StringToSometype(vItems[1]); + } + if (vItems[0] == "fpsJitterTime") { + mThreshold = SPUtilesTye::StringToSometype(vItems[1]); + } + if (vItems[0] == "catchInterval") { + mInterval = SPUtilesTye::StringToSometype(vItems[1]); + } + if (vItems[0] == "lowFps") { + lowFps = SPUtilesTye::StringToSometype(vItems[1]); + } + } + const ByTrace &bTrace = ByTrace::GetInstance(); + if (message.find("traceSum") != std::string::npos) { + int mCurNum = 1; + bTrace.SetTraceConfig(mSum, mInterval, mThreshold, lowFps, mCurNum); + } +} +SpProfiler *SpProfilerFactory::GetCmdProfilerItem(CommandType commandType, bool cmdFlag) +{ + SpProfiler *profiler = nullptr; + switch (commandType) { + case CommandType::CT_C: + if (cmdFlag) { + profiler = &CPU::GetInstance(); + } + break; + case CommandType::CT_G: + profiler = &GPU::GetInstance(); + break; + case CommandType::CT_F: + if (cmdFlag) { + profiler = &FPS::GetInstance(); + } + break; + case CommandType::CT_D: + profiler = &DDR::GetInstance(); + break; + case CommandType::CT_P: + profiler = &Power::GetInstance(); + break; + case CommandType::CT_T: + profiler = &Temperature::GetInstance(); + break; + case CommandType::CT_R: + if (cmdFlag) { + profiler = &RAM::GetInstance(); + } + break; + case CommandType::CT_NET: + profiler = &Network::GetInstance(); + break; + case CommandType::CT_NAV: + profiler = &Navigation::GetInstance(); + break; + case CommandType::CT_TTRACE: + FPS::GetInstance().SetTraceCatch(); + break; + case CommandType::CT_AS: + profiler = &AISchedule::GetInstance(); + break; + default: + break; + } + if (profiler == nullptr) { + profiler = GetCmdProfilerItemContinue(commandType, cmdFlag); + } + return profiler; +} + +SpProfiler *SpProfilerFactory::GetCmdProfilerItemContinue(CommandType commandType, bool cmdFlag) +{ + SpProfiler *profiler = nullptr; + switch (commandType) { + case CommandType::CT_SNAPSHOT: + if (cmdFlag) { + profiler = &Capture::GetInstance(); + } + break; + case CommandType::CT_THREADS: + profiler = &Threads::GetInstance().GetInstance(); + break; + case CommandType::CT_FDS: + if (cmdFlag) { + profiler = &FileDescriptor::GetInstance().GetInstance(); + } + break; + case CommandType::CT_GE: + profiler = &GameEvent::GetInstance(); + break; + case CommandType::CT_GC: { + profiler = &GpuCounter::GetInstance(); + break; + } + case CommandType::CT_O: { + profiler = &SdkDataRecv::GetInstance(); + break; + } + case CommandType::CT_FL: + case CommandType::CT_FTL: { + profiler = &Effective::GetInstance(); + break; + } + case CommandType::CT_CI: { + profiler = &CPUInfo::GetInstance(); + break; + } + case CommandType::CT_LF: { + profiler = &LockFrequency::GetInstance(); + break; + } + case CommandType::CT_HCI: { + profiler = &Hiperf::GetInstance(); + break; + } + default: + break; + } + return profiler; +} +} +} diff --git a/smartperf_device/device_command/utils/src/startup_delay.cpp b/smartperf_device/device_command/utils/src/startup_delay.cpp new file mode 100644 index 000000000..b6f5ff36d --- /dev/null +++ b/smartperf_device/device_command/utils/src/startup_delay.cpp @@ -0,0 +1,279 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "include/startup_delay.h" +#include "include/sp_utils.h" +#include "include/sp_log.h" +#include "include/common.h" + +namespace OHOS { +namespace SmartPerf { +std::vector g_pidParams; +StartUpDelay::StartUpDelay() {} +StartUpDelay::~StartUpDelay() {} +void StartUpDelay::GetTrace(const std::string &traceName) const +{ + std::string result; + std::string cmdString; + if (SPUtils::IsHmKernel()) { + cmdString = CMD_COMMAND_MAP.at(CmdCommand::HITRACE_1024); + } else { + cmdString = CMD_COMMAND_MAP.at(CmdCommand::HITRACE_2048); + } + SPUtils::LoadCmd(cmdString + traceName, result); + LOGD("GetTrace : %s", (cmdString + traceName).c_str()); + if (result.find("OpenRecording failed") != std::string::npos) { + std::string str; + std::string traceFinishStr = "hitrace --trace_finish"; + SPUtils::LoadCmd(traceFinishStr, str); + SPUtils::LoadCmd(cmdString + traceName, result); + } +} + +void StartUpDelay::GetHisysId() const +{ + int time = 10; + sleep(time); + std::string str = ""; + std::string cmd = HISYSEVENT_CMD_MAP.at(HisyseventCmd::HISYSEVENT); + SPUtils::LoadCmd(cmd, str); + std::stringstream ss(str); + std::string line = ""; + getline(ss, line); + std::stringstream ssLine(line); + std::string word = ""; + std::string secondStr; + int count = 0; + int num = 2; + while (ssLine >> word) { + count++; + if (count == num) { + secondStr = word; + break; + } + } + std::string killCmd = CMD_COMMAND_MAP.at(CmdCommand::KILL_CMD); + SPUtils::LoadCmd(killCmd + secondStr, str); +} + +void StartUpDelay::GetHisysIdAndKill() const +{ + int time = 10; + sleep(time); + std::string str = ""; + std::string cmd = HISYSEVENT_CMD_MAP.at(HisyseventCmd::HISYS_PID); + SPUtils::LoadCmd(cmd, str); + std::stringstream ss(str); + std::vector hisysIdVec; + std::string singleId; + while (ss >> singleId) { + hisysIdVec.push_back(singleId); + } + std::string killCmd = CMD_COMMAND_MAP.at(CmdCommand::KILL_CMD); + for (size_t i = 0; i < hisysIdVec.size(); i++) { + SPUtils::LoadCmd(killCmd + hisysIdVec[i], str); + } +} +bool StartUpDelay::KillSpProcess() const +{ + std::string resultPid; + std::string str; + std::string cmd = CMD_COMMAND_MAP.at(CmdCommand::PIDOF_SP); + SPUtils::LoadCmd(cmd, resultPid); + std::vector vec; + std::string token; + size_t pos = 0; + while ((pos = resultPid.find(' ')) != std::string::npos) { + token = resultPid.substr(0, pos); + vec.push_back(token); + resultPid.erase(0, pos + 1); + } + if (vec.size() > 0) { + std::string killCmd = CMD_COMMAND_MAP.at(CmdCommand::KILL_CMD); + for (size_t i = 0; i < vec.size(); i++) { + SPUtils::LoadCmd(killCmd + vec[i], str); + } + } + return false; +} + +bool StartUpDelay::GetSpClear(bool isKillTestServer) const +{ + std::string cmd = "ps -ef | grep -v grep | grep SP_daemon"; + std::string curPid = std::to_string(getpid()); + FILE *fd = popen(cmd.c_str(), "r"); + if (fd == nullptr) { + return false; + } + char buf[4096] = {'\0'}; + while ((fgets(buf, sizeof(buf), fd)) != nullptr) { + std::string line(buf); + if (isKillTestServer || line.find("testserver") == std::string::npos) { + KillTestSpdaemon(line, curPid); + } + } + pclose(fd); + return false; +} + +void StartUpDelay::ClearOldServer() const +{ + std::string curPid = std::to_string(getpid()); + std::string commandServer = CMD_COMMAND_MAP.at(CmdCommand::SERVER_GREP); + std::string resultPidServer; + std::string commandEditorServer = CMD_COMMAND_MAP.at(CmdCommand::EDITOR_SERVER_GREP); + std::string resultPidEditorServer; + + SPUtils::LoadCmdWithLinkBreak(commandServer, false, resultPidServer); + SPUtils::LoadCmdWithLinkBreak(commandEditorServer, false, resultPidEditorServer); + + std::istringstream iss(resultPidServer + '\n' + resultPidEditorServer); + std::string resultLine; + std::string killResult; + std::string killCmd = CMD_COMMAND_MAP.at(CmdCommand::KILL_CMD); + while (std::getline(iss, resultLine)) { + if (resultLine.empty() || resultLine.find("sh -c") != std::string::npos) { + continue; + } + + std::istringstream lineStream(resultLine); + std::string token; + + int count = 0; + while (lineStream >> token) { + if (count == 1) { + break; + } + count++; + } + + if (token != curPid) { + SPUtils::LoadCmd(killCmd + token, killResult); + LOGD("Find old server: %s, killed.", token.c_str()); + } + } +} +std::string StartUpDelay::ExecuteCommand(const std::vector &args) const +{ + std::string output = ""; + int pipefd[2]; + if (pipe(pipefd) == -1) { + LOGE("startup_delay::Failed to create pipe: %s", strerror(errno)); + return output; + } + pid_t pid = fork(); + if (pid == -1) { + LOGE("startup_delay::Failed to fork: %s", strerror(errno)); + close(pipefd[0]); + close(pipefd[1]); + return output; + } + if (pid == 0) { + close(pipefd[0]); + dup2(pipefd[1], STDOUT_FILENO); + close(pipefd[1]); + if (args.empty() || args[0] == nullptr) { + LOGE("startup_delay::Invalid commd"); + return output; + } + execvp(args[0], const_cast(args.data())); + LOGE("startup_delay::Failed to execute pid: %s", strerror(errno)); + _exit(EXIT_FAILURE); + } + close(pipefd[1]); + char buf[1024]; + ssize_t nread; + while ((nread = read(pipefd[0], buf, sizeof(buf) - 1)) > 0) { + if (nread == sizeof(buf) - 1) { + LOGE("startup_delay::Buffer overflow: %s", strerror(errno)); + break; + } + buf[nread] = '\0'; + output.append(buf); + } + if (nread == -1) { + LOGE("startup_delay::Failed to read from pipe: %s", strerror(errno)); + } + close(pipefd[0]); + int status; + if (waitpid(pid, &status, 0) == -1) { + LOGE("startup_delay::Failed to wait for child process: %s", strerror(errno)); + return output; + } + return output; +} + +std::string StartUpDelay::GetPidByPkg(const std::string &curPkgName, std::string* pids) const +{ + std::vector args = {"pidof", curPkgName.c_str()}; + args.push_back(nullptr); + std::string resultProcId = ExecuteCommand(args); + LOGD("StartUpDelay::resultProcId(%s)", resultProcId.c_str()); + if (!resultProcId.empty()) { + if (resultProcId.back() == '\n') { + resultProcId.pop_back(); + } + g_pidParams.clear(); + SPUtils::StrSplit(resultProcId, " ", g_pidParams); + pids == nullptr ? "" : *pids = resultProcId; + size_t endpos = resultProcId.find(" "); + if (endpos != std::string::npos) { + resultProcId = resultProcId.substr(0, endpos); + } + LOGD("startup_delay::output: (%s) (%s)", resultProcId.c_str(), + pids == nullptr ? resultProcId.c_str() : pids->c_str()); + } + return resultProcId; +} + +std::vector StartUpDelay::GetPidParams() const +{ + return g_pidParams; +} + +void StartUpDelay::KillTestSpdaemon(const std::string &line, const std::string &curPid) const +{ + std::istringstream iss(line); + std::string cmd = ""; + std::string field; + std::string cmdResult; + std::string pid = "-1"; + int count = 0; + int first = 1; + while (iss >> field) { + if (count == first) { + pid = field; + break; + } + count++; + } + if (pid != curPid) { + cmd = "kill " + pid; + SPUtils::LoadCmd(cmd, cmdResult); + } +} +} +} -- Gitee