148f512ceSopenharmony_ci/* 248f512ceSopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 348f512ceSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 448f512ceSopenharmony_ci * you may not use this file except in compliance with the License. 548f512ceSopenharmony_ci * You may obtain a copy of the License at 648f512ceSopenharmony_ci * 748f512ceSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 848f512ceSopenharmony_ci * 948f512ceSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1048f512ceSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1148f512ceSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1248f512ceSopenharmony_ci * See the License for the specific language governing permissions and 1348f512ceSopenharmony_ci * limitations under the License. 1448f512ceSopenharmony_ci */ 1548f512ceSopenharmony_ci#include "hiperf_client.h" 1648f512ceSopenharmony_ci#include <sys/wait.h> 1748f512ceSopenharmony_ci#include <algorithm> 1848f512ceSopenharmony_ci#include <cinttypes> 1948f512ceSopenharmony_ci#include <csignal> 2048f512ceSopenharmony_ci#include <cstring> 2148f512ceSopenharmony_ci#include <thread> 2248f512ceSopenharmony_ci#include <poll.h> 2348f512ceSopenharmony_ci#include <sys/prctl.h> 2448f512ceSopenharmony_ci#include <unistd.h> 2548f512ceSopenharmony_ci#include "hiperf_hilog.h" 2648f512ceSopenharmony_ci 2748f512ceSopenharmony_ciusing namespace std::chrono; 2848f512ceSopenharmony_cinamespace OHOS { 2948f512ceSopenharmony_cinamespace Developtools { 3048f512ceSopenharmony_cinamespace HiPerf { 3148f512ceSopenharmony_cinamespace HiperfClient { 3248f512ceSopenharmony_cistatic const std::string HIPERF_COMMAND_NAME = "hiperf"; 3348f512ceSopenharmony_cistatic const std::string SYSTEM_BIN_PATH = "/system/bin/"; 3448f512ceSopenharmony_cistatic const std::string CURRENT_PATH = "./"; 3548f512ceSopenharmony_cistatic const std::string PERF_DATA_NAME = "perf.data"; 3648f512ceSopenharmony_cistatic const std::string COMMAND_RECORD = "record"; 3748f512ceSopenharmony_cistatic const std::string ARG_OUTPUT_PATH = "-o"; 3848f512ceSopenharmony_cistatic const std::string ARG_DEBUG = "--verbose"; 3948f512ceSopenharmony_cistatic const std::string ARG_DEBUG_MUCH = "--much"; 4048f512ceSopenharmony_cistatic const std::string ARG_HILOG = "--hilog"; 4148f512ceSopenharmony_cistatic const std::string ARG_PIPE_INPUT = "--pipe_input"; 4248f512ceSopenharmony_cistatic const std::string ARG_PIPE_OUTPUT = "--pipe_output"; 4348f512ceSopenharmony_cistatic const std::string ARG_TARGET_SYSTEM_WIDE = "-a"; 4448f512ceSopenharmony_cistatic const std::string ARG_COMPRESS_DATA = "-z"; 4548f512ceSopenharmony_cistatic const std::string ARG_SELECT_CPUS = "-c"; 4648f512ceSopenharmony_cistatic const std::string ARG_TIME_STOP_SEC = "-d"; 4748f512ceSopenharmony_cistatic const std::string ARG_FREQUENCY = "-f"; 4848f512ceSopenharmony_cistatic const std::string ARG_PERIOD = "--period"; 4948f512ceSopenharmony_cistatic const std::string ARG_SELECT_EVENTS = "-e"; 5048f512ceSopenharmony_cistatic const std::string ARG_SELECT_GROUPS = "-g"; 5148f512ceSopenharmony_cistatic const std::string ARG_NO_INHERIT = "--no-inherit"; 5248f512ceSopenharmony_cistatic const std::string ARG_SELECT_PIDS = "-p"; 5348f512ceSopenharmony_cistatic const std::string ARG_SELECT_TIDS = "-t"; 5448f512ceSopenharmony_cistatic const std::string ARG_EXCLUDE_PERF = "--exclude-hiperf"; 5548f512ceSopenharmony_cistatic const std::string ARG_CPU_PERCENT = "--cpu-limit"; 5648f512ceSopenharmony_cistatic const std::string ARG_OFF_CPU = "--offcpu"; 5748f512ceSopenharmony_cistatic const std::string ARG_CALL_GRAPH = "--call-stack"; 5848f512ceSopenharmony_cistatic const std::string ARG_DELAY_UNWIND = "--delay-unwind"; 5948f512ceSopenharmony_cistatic const std::string ARG_DISABLE_UNWIND = "--disable-unwind"; 6048f512ceSopenharmony_cistatic const std::string ARG_DISABLE_CALLSTACK_MERGE = "--disable-callstack-expand"; 6148f512ceSopenharmony_cistatic const std::string ARG_SYMBOL_DIR = "--symbol-dir"; 6248f512ceSopenharmony_cistatic const std::string ARG_DATA_LIMIT = "--data-limit"; 6348f512ceSopenharmony_cistatic const std::string ARG_APP_PACKAGE = "--app"; 6448f512ceSopenharmony_cistatic const std::string ARG_CLOCK_ID = "--clockid"; 6548f512ceSopenharmony_cistatic const std::string ARG_VEC_BRANCH_SAMPLE_TYPES = "-j"; 6648f512ceSopenharmony_cistatic const std::string ARG_MMAP_PAGES = "-m"; 6748f512ceSopenharmony_cistatic const std::string ARG_REPORT = "--report"; 6848f512ceSopenharmony_ci 6948f512ceSopenharmony_cistatic constexpr int DEFAULT_DURATION_TIME = 10; 7048f512ceSopenharmony_cistatic constexpr int DEFAULT_FREQUENCY_TIME = 100; 7148f512ceSopenharmony_cistatic constexpr uint64_t PIPE_READ = 0; 7248f512ceSopenharmony_cistatic constexpr uint64_t PIPE_WRITE = 1; 7348f512ceSopenharmony_cistatic constexpr ssize_t ERRINFOLEN = 512; 7448f512ceSopenharmony_cistatic constexpr size_t SIZE_ARGV_TAIL = 1; // nullptr 7548f512ceSopenharmony_ci 7648f512ceSopenharmony_civoid RecordOption::SetOption(const std::string &name, bool enable) 7748f512ceSopenharmony_ci{ 7848f512ceSopenharmony_ci auto it = std::find(args_.begin(), args_.end(), name); 7948f512ceSopenharmony_ci if (enable) { 8048f512ceSopenharmony_ci if (it == args_.end()) { 8148f512ceSopenharmony_ci args_.emplace_back(name); 8248f512ceSopenharmony_ci } 8348f512ceSopenharmony_ci 8448f512ceSopenharmony_ci return; 8548f512ceSopenharmony_ci } 8648f512ceSopenharmony_ci if (it != args_.end()) { 8748f512ceSopenharmony_ci args_.erase(it); 8848f512ceSopenharmony_ci return; 8948f512ceSopenharmony_ci } 9048f512ceSopenharmony_ci} 9148f512ceSopenharmony_ci 9248f512ceSopenharmony_civoid RecordOption::SetOption(const std::string &name, int value) 9348f512ceSopenharmony_ci{ 9448f512ceSopenharmony_ci auto it = std::find(args_.begin(), args_.end(), name); 9548f512ceSopenharmony_ci if (it != args_.end()) { 9648f512ceSopenharmony_ci it++; 9748f512ceSopenharmony_ci *it = std::to_string(value); 9848f512ceSopenharmony_ci return; 9948f512ceSopenharmony_ci } 10048f512ceSopenharmony_ci 10148f512ceSopenharmony_ci args_.emplace_back(name); 10248f512ceSopenharmony_ci args_.emplace_back(std::to_string(value)); 10348f512ceSopenharmony_ci return; 10448f512ceSopenharmony_ci} 10548f512ceSopenharmony_ci 10648f512ceSopenharmony_civoid RecordOption::SetOption(const std::string &name, const std::vector<int> &vInt) 10748f512ceSopenharmony_ci{ 10848f512ceSopenharmony_ci auto it = std::find(args_.begin(), args_.end(), name); 10948f512ceSopenharmony_ci if (vInt.empty()) { 11048f512ceSopenharmony_ci if (it != args_.end()) { 11148f512ceSopenharmony_ci it = args_.erase(it); // remove key 11248f512ceSopenharmony_ci if (it != args_.end()) { 11348f512ceSopenharmony_ci args_.erase(it); // remove value 11448f512ceSopenharmony_ci } 11548f512ceSopenharmony_ci } 11648f512ceSopenharmony_ci return; 11748f512ceSopenharmony_ci } 11848f512ceSopenharmony_ci 11948f512ceSopenharmony_ci std::string str; 12048f512ceSopenharmony_ci for (auto n : vInt) { 12148f512ceSopenharmony_ci str.append(std::to_string(n)); 12248f512ceSopenharmony_ci str.append(","); 12348f512ceSopenharmony_ci } 12448f512ceSopenharmony_ci str.pop_back(); // remove the last ',' 12548f512ceSopenharmony_ci 12648f512ceSopenharmony_ci if (it != args_.end()) { 12748f512ceSopenharmony_ci it++; 12848f512ceSopenharmony_ci *it = str; 12948f512ceSopenharmony_ci return; 13048f512ceSopenharmony_ci } 13148f512ceSopenharmony_ci args_.emplace_back(name); 13248f512ceSopenharmony_ci args_.emplace_back(str); 13348f512ceSopenharmony_ci} 13448f512ceSopenharmony_ci 13548f512ceSopenharmony_civoid RecordOption::SetOption(const std::string &name, const std::string &str) 13648f512ceSopenharmony_ci{ 13748f512ceSopenharmony_ci auto it = std::find(args_.begin(), args_.end(), name); 13848f512ceSopenharmony_ci if (str.empty()) { 13948f512ceSopenharmony_ci if (it != args_.end()) { 14048f512ceSopenharmony_ci args_.erase(it); 14148f512ceSopenharmony_ci args_.erase(it); // remove value 14248f512ceSopenharmony_ci } 14348f512ceSopenharmony_ci return; 14448f512ceSopenharmony_ci } 14548f512ceSopenharmony_ci if (it != args_.end()) { 14648f512ceSopenharmony_ci it++; 14748f512ceSopenharmony_ci *it = str; 14848f512ceSopenharmony_ci return; 14948f512ceSopenharmony_ci } 15048f512ceSopenharmony_ci args_.emplace_back(name); 15148f512ceSopenharmony_ci args_.emplace_back(str); 15248f512ceSopenharmony_ci} 15348f512ceSopenharmony_ci 15448f512ceSopenharmony_civoid RecordOption::SetOption(const std::string &name, const std::vector<std::string> &vStr) 15548f512ceSopenharmony_ci{ 15648f512ceSopenharmony_ci auto it = std::find(args_.begin(), args_.end(), name); 15748f512ceSopenharmony_ci if (vStr.empty()) { 15848f512ceSopenharmony_ci if (it != args_.end()) { 15948f512ceSopenharmony_ci args_.erase(it); 16048f512ceSopenharmony_ci args_.erase(it); // remove value 16148f512ceSopenharmony_ci } 16248f512ceSopenharmony_ci return; 16348f512ceSopenharmony_ci } 16448f512ceSopenharmony_ci 16548f512ceSopenharmony_ci std::string str; 16648f512ceSopenharmony_ci for (auto substr : vStr) { 16748f512ceSopenharmony_ci str.append(substr); 16848f512ceSopenharmony_ci str.append(","); 16948f512ceSopenharmony_ci } 17048f512ceSopenharmony_ci str.pop_back(); // remove the last ',' 17148f512ceSopenharmony_ci 17248f512ceSopenharmony_ci if (it != args_.end()) { 17348f512ceSopenharmony_ci it++; 17448f512ceSopenharmony_ci *it = str; 17548f512ceSopenharmony_ci return; 17648f512ceSopenharmony_ci } 17748f512ceSopenharmony_ci args_.emplace_back(name); 17848f512ceSopenharmony_ci args_.emplace_back(str); 17948f512ceSopenharmony_ci} 18048f512ceSopenharmony_ci 18148f512ceSopenharmony_civoid RecordOption::SetTargetSystemWide(bool enable) 18248f512ceSopenharmony_ci{ 18348f512ceSopenharmony_ci SetOption(ARG_TARGET_SYSTEM_WIDE, enable); 18448f512ceSopenharmony_ci} 18548f512ceSopenharmony_ci 18648f512ceSopenharmony_civoid RecordOption::SetCompressData(bool enable) 18748f512ceSopenharmony_ci{ 18848f512ceSopenharmony_ci SetOption(ARG_COMPRESS_DATA, enable); 18948f512ceSopenharmony_ci} 19048f512ceSopenharmony_ci 19148f512ceSopenharmony_civoid RecordOption::SetSelectCpus(const std::vector<int> &cpus) 19248f512ceSopenharmony_ci{ 19348f512ceSopenharmony_ci SetOption(ARG_SELECT_CPUS, cpus); 19448f512ceSopenharmony_ci} 19548f512ceSopenharmony_ci 19648f512ceSopenharmony_civoid RecordOption::SetTimeStopSec(int timeStopSec) 19748f512ceSopenharmony_ci{ 19848f512ceSopenharmony_ci this->timeSpec_ = true; 19948f512ceSopenharmony_ci SetOption(ARG_TIME_STOP_SEC, timeStopSec); 20048f512ceSopenharmony_ci} 20148f512ceSopenharmony_ci 20248f512ceSopenharmony_civoid RecordOption::SetFrequency(int frequency) 20348f512ceSopenharmony_ci{ 20448f512ceSopenharmony_ci SetOption(ARG_FREQUENCY, frequency); 20548f512ceSopenharmony_ci} 20648f512ceSopenharmony_ci 20748f512ceSopenharmony_civoid RecordOption::SetPeriod(int period) 20848f512ceSopenharmony_ci{ 20948f512ceSopenharmony_ci SetOption(ARG_PERIOD, period); 21048f512ceSopenharmony_ci} 21148f512ceSopenharmony_ci 21248f512ceSopenharmony_civoid RecordOption::SetSelectEvents(const std::vector<std::string> &selectEvents) 21348f512ceSopenharmony_ci{ 21448f512ceSopenharmony_ci SetOption(ARG_SELECT_EVENTS, selectEvents); 21548f512ceSopenharmony_ci} 21648f512ceSopenharmony_ci 21748f512ceSopenharmony_civoid RecordOption::SetSelectGroups(const std::vector<std::string> &selectGroups) 21848f512ceSopenharmony_ci{ 21948f512ceSopenharmony_ci SetOption(ARG_SELECT_GROUPS, selectGroups); 22048f512ceSopenharmony_ci} 22148f512ceSopenharmony_ci 22248f512ceSopenharmony_civoid RecordOption::SetNoInherit(bool enable) 22348f512ceSopenharmony_ci{ 22448f512ceSopenharmony_ci SetOption(ARG_NO_INHERIT, enable); 22548f512ceSopenharmony_ci} 22648f512ceSopenharmony_ci 22748f512ceSopenharmony_civoid RecordOption::SetSelectPids(const std::vector<pid_t> &selectPids) 22848f512ceSopenharmony_ci{ 22948f512ceSopenharmony_ci SetOption(ARG_SELECT_PIDS, selectPids); 23048f512ceSopenharmony_ci} 23148f512ceSopenharmony_ci 23248f512ceSopenharmony_civoid RecordOption::SetCallStackSamplingConfigs(int duration) 23348f512ceSopenharmony_ci{ 23448f512ceSopenharmony_ci if (duration <= 0) { 23548f512ceSopenharmony_ci duration = DEFAULT_DURATION_TIME; 23648f512ceSopenharmony_ci } 23748f512ceSopenharmony_ci RecordOption opt; 23848f512ceSopenharmony_ci SetSelectEvents(opt.GetSelectEvents()); 23948f512ceSopenharmony_ci SetTimeStopSec(duration); 24048f512ceSopenharmony_ci SetFrequency(DEFAULT_FREQUENCY_TIME); 24148f512ceSopenharmony_ci SetCallGraph("fp"); 24248f512ceSopenharmony_ci} 24348f512ceSopenharmony_ci 24448f512ceSopenharmony_civoid RecordOption::SetSelectTids(const std::vector<pid_t> &selectTids) 24548f512ceSopenharmony_ci{ 24648f512ceSopenharmony_ci SetOption(ARG_SELECT_TIDS, selectTids); 24748f512ceSopenharmony_ci} 24848f512ceSopenharmony_ci 24948f512ceSopenharmony_civoid RecordOption::SetExcludePerf(bool excludePerf) 25048f512ceSopenharmony_ci{ 25148f512ceSopenharmony_ci SetOption(ARG_EXCLUDE_PERF, excludePerf); 25248f512ceSopenharmony_ci} 25348f512ceSopenharmony_ci 25448f512ceSopenharmony_civoid RecordOption::SetCpuPercent(int cpuPercent) 25548f512ceSopenharmony_ci{ 25648f512ceSopenharmony_ci SetOption(ARG_CPU_PERCENT, cpuPercent); 25748f512ceSopenharmony_ci} 25848f512ceSopenharmony_ci 25948f512ceSopenharmony_civoid RecordOption::SetOffCPU(bool offCPU) 26048f512ceSopenharmony_ci{ 26148f512ceSopenharmony_ci SetOption(ARG_OFF_CPU, offCPU); 26248f512ceSopenharmony_ci} 26348f512ceSopenharmony_ci 26448f512ceSopenharmony_civoid RecordOption::SetCallGraph(const std::string &callGraph) 26548f512ceSopenharmony_ci{ 26648f512ceSopenharmony_ci SetOption(ARG_CALL_GRAPH, callGraph); 26748f512ceSopenharmony_ci} 26848f512ceSopenharmony_ci 26948f512ceSopenharmony_civoid RecordOption::SetDelayUnwind(bool delayUnwind) 27048f512ceSopenharmony_ci{ 27148f512ceSopenharmony_ci SetOption(ARG_DELAY_UNWIND, delayUnwind); 27248f512ceSopenharmony_ci} 27348f512ceSopenharmony_ci 27448f512ceSopenharmony_civoid RecordOption::SetDisableUnwind(bool disableUnwind) 27548f512ceSopenharmony_ci{ 27648f512ceSopenharmony_ci SetOption(ARG_DISABLE_UNWIND, disableUnwind); 27748f512ceSopenharmony_ci} 27848f512ceSopenharmony_ci 27948f512ceSopenharmony_civoid RecordOption::SetDisableCallstackMerge(bool disableCallstackMerge) 28048f512ceSopenharmony_ci{ 28148f512ceSopenharmony_ci SetOption(ARG_DISABLE_CALLSTACK_MERGE, disableCallstackMerge); 28248f512ceSopenharmony_ci} 28348f512ceSopenharmony_ci 28448f512ceSopenharmony_civoid RecordOption::SetSymbolDir(const std::string &symbolDir_) 28548f512ceSopenharmony_ci{ 28648f512ceSopenharmony_ci SetOption(ARG_SYMBOL_DIR, symbolDir_); 28748f512ceSopenharmony_ci} 28848f512ceSopenharmony_ci 28948f512ceSopenharmony_civoid RecordOption::SetDataLimit(const std::string &limit) 29048f512ceSopenharmony_ci{ 29148f512ceSopenharmony_ci SetOption(ARG_DATA_LIMIT, limit); 29248f512ceSopenharmony_ci} 29348f512ceSopenharmony_ci 29448f512ceSopenharmony_civoid RecordOption::SetAppPackage(const std::string &appPackage) 29548f512ceSopenharmony_ci{ 29648f512ceSopenharmony_ci SetOption(ARG_APP_PACKAGE, appPackage); 29748f512ceSopenharmony_ci} 29848f512ceSopenharmony_ci 29948f512ceSopenharmony_civoid RecordOption::SetClockId(const std::string &clockId) 30048f512ceSopenharmony_ci{ 30148f512ceSopenharmony_ci SetOption(ARG_CLOCK_ID, clockId); 30248f512ceSopenharmony_ci} 30348f512ceSopenharmony_ci 30448f512ceSopenharmony_civoid RecordOption::SetVecBranchSampleTypes(const std::vector<std::string> &vecBranchSampleTypes) 30548f512ceSopenharmony_ci{ 30648f512ceSopenharmony_ci SetOption(ARG_VEC_BRANCH_SAMPLE_TYPES, vecBranchSampleTypes); 30748f512ceSopenharmony_ci} 30848f512ceSopenharmony_ci 30948f512ceSopenharmony_civoid RecordOption::SetMmapPages(int mmapPages) 31048f512ceSopenharmony_ci{ 31148f512ceSopenharmony_ci SetOption(ARG_MMAP_PAGES, mmapPages); 31248f512ceSopenharmony_ci} 31348f512ceSopenharmony_ci 31448f512ceSopenharmony_civoid RecordOption::SetReport(bool report) 31548f512ceSopenharmony_ci{ 31648f512ceSopenharmony_ci SetOption(ARG_REPORT, report); 31748f512ceSopenharmony_ci} 31848f512ceSopenharmony_ci 31948f512ceSopenharmony_ciClient::Client(const std::string &outputDir) 32048f512ceSopenharmony_ci{ 32148f512ceSopenharmony_ci HIPERF_HILOGI(MODULE_CPP_API, "%" HILOG_PUBLIC "s default init with %" HILOG_PUBLIC "s\n", 32248f512ceSopenharmony_ci __FUNCTION__, outputDir.c_str()); 32348f512ceSopenharmony_ci Setup(outputDir); 32448f512ceSopenharmony_ci} 32548f512ceSopenharmony_ci 32648f512ceSopenharmony_cibool Client::Setup(std::string outputDir) 32748f512ceSopenharmony_ci{ 32848f512ceSopenharmony_ci std::string CurrentCommandPath = CURRENT_PATH + HIPERF_COMMAND_NAME; 32948f512ceSopenharmony_ci std::string SystemCommandPath = SYSTEM_BIN_PATH + HIPERF_COMMAND_NAME; 33048f512ceSopenharmony_ci std::string TempCommandPath = TempBinPath + HIPERF_COMMAND_NAME; 33148f512ceSopenharmony_ci 33248f512ceSopenharmony_ci if (!outputDir.empty() && outputDir.back() != '/') { 33348f512ceSopenharmony_ci outputDir.push_back('/'); 33448f512ceSopenharmony_ci } 33548f512ceSopenharmony_ci HIPERF_HILOGI(MODULE_CPP_API, "outputDir setup to %" HILOG_PUBLIC "s\n", outputDir.c_str()); 33648f512ceSopenharmony_ci 33748f512ceSopenharmony_ci // found command path 33848f512ceSopenharmony_ci if (access(SystemCommandPath.c_str(), X_OK) == 0) { 33948f512ceSopenharmony_ci executeCommandPath_ = SystemCommandPath; 34048f512ceSopenharmony_ci } else if (access(TempCommandPath.c_str(), X_OK) == 0) { 34148f512ceSopenharmony_ci executeCommandPath_ = TempCommandPath; 34248f512ceSopenharmony_ci } else if (access(CurrentCommandPath.c_str(), X_OK) == 0) { 34348f512ceSopenharmony_ci executeCommandPath_ = CurrentCommandPath; 34448f512ceSopenharmony_ci } else { 34548f512ceSopenharmony_ci HIPERF_HILOGI(MODULE_CPP_API, "no hiperf command found\n"); 34648f512ceSopenharmony_ci return ready_; 34748f512ceSopenharmony_ci } 34848f512ceSopenharmony_ci 34948f512ceSopenharmony_ci // check output path 35048f512ceSopenharmony_ci // found command path 35148f512ceSopenharmony_ci if (access(outputDir.c_str(), W_OK) == 0) { 35248f512ceSopenharmony_ci outputDir_ = outputDir; 35348f512ceSopenharmony_ci } else if (access(CURRENT_PATH.c_str(), W_OK) == 0) { 35448f512ceSopenharmony_ci outputDir_ = CURRENT_PATH; 35548f512ceSopenharmony_ci } else { 35648f512ceSopenharmony_ci HIPERF_HILOGI(MODULE_CPP_API, "no writeable output path found\n"); 35748f512ceSopenharmony_ci return ready_; 35848f512ceSopenharmony_ci } 35948f512ceSopenharmony_ci outputFileName_ = PERF_DATA_NAME; 36048f512ceSopenharmony_ci 36148f512ceSopenharmony_ci myPid_ = getpid(); 36248f512ceSopenharmony_ci 36348f512ceSopenharmony_ci // every thing check ok 36448f512ceSopenharmony_ci ready_ = true; 36548f512ceSopenharmony_ci 36648f512ceSopenharmony_ci return ready_; 36748f512ceSopenharmony_ci} 36848f512ceSopenharmony_ci 36948f512ceSopenharmony_ciClient::~Client() 37048f512ceSopenharmony_ci{ 37148f512ceSopenharmony_ci KillChild(); 37248f512ceSopenharmony_ci} 37348f512ceSopenharmony_ci 37448f512ceSopenharmony_cibool Client::IsReady() 37548f512ceSopenharmony_ci{ 37648f512ceSopenharmony_ci return ready_; 37748f512ceSopenharmony_ci} 37848f512ceSopenharmony_ci 37948f512ceSopenharmony_civoid Client::SetDebugMode() 38048f512ceSopenharmony_ci{ 38148f512ceSopenharmony_ci debug_ = true; 38248f512ceSopenharmony_ci} 38348f512ceSopenharmony_ci 38448f512ceSopenharmony_civoid Client::SetDebugMuchMode() 38548f512ceSopenharmony_ci{ 38648f512ceSopenharmony_ci debugMuch_ = true; 38748f512ceSopenharmony_ci} 38848f512ceSopenharmony_ci 38948f512ceSopenharmony_cibool Client::Start() 39048f512ceSopenharmony_ci{ 39148f512ceSopenharmony_ci HIPERF_HILOGI(MODULE_CPP_API, "Client:%" HILOG_PUBLIC "s\n", __FUNCTION__); 39248f512ceSopenharmony_ci 39348f512ceSopenharmony_ci std::vector<std::string> args; 39448f512ceSopenharmony_ci args.push_back("-p"); 39548f512ceSopenharmony_ci args.push_back(std::to_string(getpid())); 39648f512ceSopenharmony_ci return Start(args); 39748f512ceSopenharmony_ci} 39848f512ceSopenharmony_ci 39948f512ceSopenharmony_civoid Client::PrepareExecCmd(std::vector<std::string> &cmd) 40048f512ceSopenharmony_ci{ 40148f512ceSopenharmony_ci cmd.clear(); 40248f512ceSopenharmony_ci cmd.emplace_back(executeCommandPath_); 40348f512ceSopenharmony_ci 40448f512ceSopenharmony_ci if (debug_) { 40548f512ceSopenharmony_ci cmd.emplace_back(ARG_DEBUG); 40648f512ceSopenharmony_ci } else if (debugMuch_) { 40748f512ceSopenharmony_ci cmd.emplace_back(ARG_DEBUG_MUCH); 40848f512ceSopenharmony_ci } 40948f512ceSopenharmony_ci 41048f512ceSopenharmony_ci if (hilog_) { 41148f512ceSopenharmony_ci cmd.emplace_back(ARG_HILOG); 41248f512ceSopenharmony_ci } 41348f512ceSopenharmony_ci 41448f512ceSopenharmony_ci cmd.emplace_back(COMMAND_RECORD); 41548f512ceSopenharmony_ci cmd.emplace_back(ARG_OUTPUT_PATH); 41648f512ceSopenharmony_ci cmd.emplace_back(GetOutputPerfDataPath()); 41748f512ceSopenharmony_ci} 41848f512ceSopenharmony_ci 41948f512ceSopenharmony_civoid Client::GetExecCmd(std::vector<std::string> &cmd, int pipeIn, int pipeOut, 42048f512ceSopenharmony_ci const std::vector<std::string> &args) 42148f512ceSopenharmony_ci{ 42248f512ceSopenharmony_ci PrepareExecCmd(cmd); 42348f512ceSopenharmony_ci cmd.emplace_back(ARG_PIPE_INPUT); 42448f512ceSopenharmony_ci cmd.emplace_back(std::to_string(pipeIn)); 42548f512ceSopenharmony_ci cmd.emplace_back(ARG_PIPE_OUTPUT); 42648f512ceSopenharmony_ci cmd.emplace_back(std::to_string(pipeOut)); 42748f512ceSopenharmony_ci 42848f512ceSopenharmony_ci cmd.insert(cmd.end(), args.begin(), args.end()); 42948f512ceSopenharmony_ci} 43048f512ceSopenharmony_ci 43148f512ceSopenharmony_civoid Client::GetExecCmd(std::vector<std::string> &cmd, 43248f512ceSopenharmony_ci const std::vector<std::string> &args) 43348f512ceSopenharmony_ci{ 43448f512ceSopenharmony_ci PrepareExecCmd(cmd); 43548f512ceSopenharmony_ci 43648f512ceSopenharmony_ci cmd.insert(cmd.end(), args.begin(), args.end()); 43748f512ceSopenharmony_ci} 43848f512ceSopenharmony_ci 43948f512ceSopenharmony_cibool Client::Start(const std::vector<std::string> &args, bool immediately) 44048f512ceSopenharmony_ci{ 44148f512ceSopenharmony_ci HIPERF_HILOGI(MODULE_CPP_API, "Client:%" HILOG_PUBLIC "s\n", __FUNCTION__); 44248f512ceSopenharmony_ci if (!ready_) { 44348f512ceSopenharmony_ci HIPERF_HILOGI(MODULE_CPP_API, "Client:hiperf not ready.\n"); 44448f512ceSopenharmony_ci return false; 44548f512ceSopenharmony_ci } 44648f512ceSopenharmony_ci 44748f512ceSopenharmony_ci int clientToServerFd[2]; 44848f512ceSopenharmony_ci int serverToClientFd[2]; 44948f512ceSopenharmony_ci if (pipe(clientToServerFd) != 0) { 45048f512ceSopenharmony_ci char errInfo[ERRINFOLEN] = { 0 }; 45148f512ceSopenharmony_ci strerror_r(errno, errInfo, ERRINFOLEN); 45248f512ceSopenharmony_ci HIPERF_HILOGI(MODULE_CPP_API, "failed to create pipe: %" HILOG_PUBLIC "s", errInfo); 45348f512ceSopenharmony_ci return false; 45448f512ceSopenharmony_ci } else if (pipe(serverToClientFd) != 0) { 45548f512ceSopenharmony_ci char errInfo[ERRINFOLEN] = { 0 }; 45648f512ceSopenharmony_ci strerror_r(errno, errInfo, ERRINFOLEN); 45748f512ceSopenharmony_ci HIPERF_HILOGI(MODULE_CPP_API, "failed to create pipe: %" HILOG_PUBLIC "s", errInfo); 45848f512ceSopenharmony_ci close(clientToServerFd[PIPE_READ]); 45948f512ceSopenharmony_ci close(clientToServerFd[PIPE_WRITE]); 46048f512ceSopenharmony_ci return false; 46148f512ceSopenharmony_ci } 46248f512ceSopenharmony_ci 46348f512ceSopenharmony_ci hperfPrePid_ = fork(); 46448f512ceSopenharmony_ci if (hperfPrePid_ == -1) { 46548f512ceSopenharmony_ci char errInfo[ERRINFOLEN] = { 0 }; 46648f512ceSopenharmony_ci strerror_r(errno, errInfo, ERRINFOLEN); 46748f512ceSopenharmony_ci HIPERF_HILOGI(MODULE_CPP_API, "failed to fork: %" HILOG_PUBLIC "s", errInfo); 46848f512ceSopenharmony_ci close(clientToServerFd[PIPE_READ]); 46948f512ceSopenharmony_ci close(clientToServerFd[PIPE_WRITE]); 47048f512ceSopenharmony_ci close(serverToClientFd[PIPE_READ]); 47148f512ceSopenharmony_ci close(serverToClientFd[PIPE_WRITE]); 47248f512ceSopenharmony_ci return false; 47348f512ceSopenharmony_ci } else if (hperfPrePid_ == 0) { 47448f512ceSopenharmony_ci // child process 47548f512ceSopenharmony_ci close(clientToServerFd[PIPE_WRITE]); 47648f512ceSopenharmony_ci close(serverToClientFd[PIPE_READ]); 47748f512ceSopenharmony_ci 47848f512ceSopenharmony_ci std::vector<std::string> cmd; 47948f512ceSopenharmony_ci GetExecCmd(cmd, clientToServerFd[PIPE_READ], serverToClientFd[PIPE_WRITE], args); 48048f512ceSopenharmony_ci ChildRunExecv(cmd); 48148f512ceSopenharmony_ci } else { 48248f512ceSopenharmony_ci // parent process 48348f512ceSopenharmony_ci close(clientToServerFd[PIPE_READ]); 48448f512ceSopenharmony_ci close(serverToClientFd[PIPE_WRITE]); 48548f512ceSopenharmony_ci 48648f512ceSopenharmony_ci clientToServerFd_ = clientToServerFd[PIPE_WRITE]; 48748f512ceSopenharmony_ci serverToClientFd_ = serverToClientFd[PIPE_READ]; 48848f512ceSopenharmony_ci } 48948f512ceSopenharmony_ci using namespace std::chrono_literals; 49048f512ceSopenharmony_ci if (!WaitCommandReply(2000ms)) { 49148f512ceSopenharmony_ci HIPERF_HILOGI(MODULE_CPP_API, "start failed . lets kill it"); 49248f512ceSopenharmony_ci KillChild(); 49348f512ceSopenharmony_ci return false; 49448f512ceSopenharmony_ci } 49548f512ceSopenharmony_ci if (immediately) { 49648f512ceSopenharmony_ci return StartRun(); 49748f512ceSopenharmony_ci } 49848f512ceSopenharmony_ci return true; 49948f512ceSopenharmony_ci} 50048f512ceSopenharmony_ci 50148f512ceSopenharmony_cibool Client::Start(const RecordOption &option) 50248f512ceSopenharmony_ci{ 50348f512ceSopenharmony_ci HIPERF_HILOGI(MODULE_CPP_API, "Client:%" HILOG_PUBLIC "s\n", __FUNCTION__); 50448f512ceSopenharmony_ci if (!option.GetOutputFileName().empty()) { 50548f512ceSopenharmony_ci outputFileName_ = option.GetOutputFileName(); 50648f512ceSopenharmony_ci } 50748f512ceSopenharmony_ci if (option.IsTimeSpecified()) { 50848f512ceSopenharmony_ci return RunHiperfCmdSync(option); 50948f512ceSopenharmony_ci } 51048f512ceSopenharmony_ci return Start(option.GetOptionVecString()); 51148f512ceSopenharmony_ci} 51248f512ceSopenharmony_ci 51348f512ceSopenharmony_civoid Client::ChildRunExecv(std::vector<std::string> &cmd) 51448f512ceSopenharmony_ci{ 51548f512ceSopenharmony_ci // conver vector to array for execvp() 51648f512ceSopenharmony_ci char *argv[cmd.size() + SIZE_ARGV_TAIL]; 51748f512ceSopenharmony_ci size_t i = 0; 51848f512ceSopenharmony_ci for (i = 0; i < cmd.size(); ++i) { 51948f512ceSopenharmony_ci HIPERF_HILOGI(MODULE_CPP_API, "args %" HILOG_PUBLIC "zu : %" HILOG_PUBLIC "s", i, 52048f512ceSopenharmony_ci cmd[i].c_str()); 52148f512ceSopenharmony_ci argv[i] = cmd[i].data(); 52248f512ceSopenharmony_ci } 52348f512ceSopenharmony_ci argv[i] = nullptr; 52448f512ceSopenharmony_ci 52548f512ceSopenharmony_ci execv(argv[0], argv); 52648f512ceSopenharmony_ci 52748f512ceSopenharmony_ci // never reach the following line, unless calling of execv function failed. 52848f512ceSopenharmony_ci char errInfo[ERRINFOLEN] = { 0 }; 52948f512ceSopenharmony_ci strerror_r(errno, errInfo, ERRINFOLEN); 53048f512ceSopenharmony_ci HIPERF_HILOGI(MODULE_CPP_API, 53148f512ceSopenharmony_ci "failed to call exec: '%" HILOG_PUBLIC "s' %" HILOG_PUBLIC "s\n", 53248f512ceSopenharmony_ci executeCommandPath_.c_str(), errInfo); 53348f512ceSopenharmony_ci exit(EXIT_FAILURE); // EXIT_FAILURE 1 53448f512ceSopenharmony_ci} 53548f512ceSopenharmony_ci 53648f512ceSopenharmony_cibool Client::ParentWait(pid_t &wpid, pid_t pid, int &childStatus) 53748f512ceSopenharmony_ci{ 53848f512ceSopenharmony_ci bool ret = false; 53948f512ceSopenharmony_ci do { 54048f512ceSopenharmony_ci // blocking... 54148f512ceSopenharmony_ci int option; 54248f512ceSopenharmony_ci#ifdef WCONTINUED 54348f512ceSopenharmony_ci option = WUNTRACED | WCONTINUED; 54448f512ceSopenharmony_ci#else 54548f512ceSopenharmony_ci option = WUNTRACED; 54648f512ceSopenharmony_ci#endif 54748f512ceSopenharmony_ci wpid = waitpid(pid, &childStatus, option); 54848f512ceSopenharmony_ci if (wpid == -1) { 54948f512ceSopenharmony_ci perror("waitpid"); 55048f512ceSopenharmony_ci return false; 55148f512ceSopenharmony_ci } 55248f512ceSopenharmony_ci 55348f512ceSopenharmony_ci if (WIFEXITED(childStatus)) { 55448f512ceSopenharmony_ci // child normally exit 55548f512ceSopenharmony_ci // WEXITSTATUS(childStatus) value : 55648f512ceSopenharmony_ci // true -> Calling of execv func successed, and recording finished 55748f512ceSopenharmony_ci // and child will return the value of recording process's retVal 55848f512ceSopenharmony_ci // false -> Calling of execv func failed, child will output errInfo 55948f512ceSopenharmony_ci ret = WEXITSTATUS(childStatus) == 0 ? true : false; 56048f512ceSopenharmony_ci HIPERF_HILOGI(MODULE_CPP_API, 56148f512ceSopenharmony_ci "Hiperf Api Child normally exit Calling of execv : '%" HILOG_PUBLIC "s' \n", 56248f512ceSopenharmony_ci ret ? "success" : "failed"); 56348f512ceSopenharmony_ci return ret; 56448f512ceSopenharmony_ci } else if (WIFSIGNALED(childStatus)) { 56548f512ceSopenharmony_ci // child was killed by SIGKILL 56648f512ceSopenharmony_ci HIPERF_HILOGI(MODULE_CPP_API, "Hiperf recording process was killed by signal SIGKILL\n"); 56748f512ceSopenharmony_ci ret = false; 56848f512ceSopenharmony_ci return ret; 56948f512ceSopenharmony_ci } else if (WIFSTOPPED(childStatus)) { 57048f512ceSopenharmony_ci // child was stopped by SIGSTOP, and waiting for SIGCONT 57148f512ceSopenharmony_ci HIPERF_HILOGI(MODULE_CPP_API, "Hiperf recording process was stopped by signal SIGSTOP\n"); 57248f512ceSopenharmony_ci#ifdef WIFCONTINUED 57348f512ceSopenharmony_ci } else if (WIFCONTINUED(childStatus)) { 57448f512ceSopenharmony_ci // child was continued by SIGCONT 57548f512ceSopenharmony_ci HIPERF_HILOGI(MODULE_CPP_API, "Hiperf recording process was continued\n by SIGCONT"); 57648f512ceSopenharmony_ci#endif 57748f512ceSopenharmony_ci } else { 57848f512ceSopenharmony_ci // non-standard case, may never happen 57948f512ceSopenharmony_ci HIPERF_HILOGI(MODULE_CPP_API, "Hiperf recording process Unexpected status\n"); 58048f512ceSopenharmony_ci } 58148f512ceSopenharmony_ci } while (!WIFEXITED(childStatus) && !WIFSIGNALED(childStatus)); 58248f512ceSopenharmony_ci 58348f512ceSopenharmony_ci // normal exit. 58448f512ceSopenharmony_ci if (WIFEXITED(childStatus)) { 58548f512ceSopenharmony_ci ret = WEXITSTATUS(childStatus) == HIPERF_EXIT_CODE; 58648f512ceSopenharmony_ci } else { 58748f512ceSopenharmony_ci // signal exit, means Hiperf recording process may occur some runtime errors. 58848f512ceSopenharmony_ci HIPERF_HILOGI(MODULE_CPP_API, 58948f512ceSopenharmony_ci "Hiperf recording occurs some runtime errors, end with signal : %" 59048f512ceSopenharmony_ci HILOG_PUBLIC "d, exit status : %" HILOG_PUBLIC "d\n", 59148f512ceSopenharmony_ci WIFSIGNALED(childStatus), WEXITSTATUS(childStatus)); 59248f512ceSopenharmony_ci ret = false; 59348f512ceSopenharmony_ci } 59448f512ceSopenharmony_ci return ret; 59548f512ceSopenharmony_ci} 59648f512ceSopenharmony_ci 59748f512ceSopenharmony_ci 59848f512ceSopenharmony_cibool Client::RunHiperfCmdSync(const RecordOption &option) 59948f512ceSopenharmony_ci{ 60048f512ceSopenharmony_ci HIPERF_HILOGI(MODULE_CPP_API, "Client:%" HILOG_PUBLIC "s\n", __FUNCTION__); 60148f512ceSopenharmony_ci if (!ready_) { 60248f512ceSopenharmony_ci HIPERF_HILOGI(MODULE_CPP_API, "Client:hiperf not ready.\n"); 60348f512ceSopenharmony_ci return false; 60448f512ceSopenharmony_ci } 60548f512ceSopenharmony_ci const std::vector<std::string> &args = option.GetOptionVecString(); 60648f512ceSopenharmony_ci 60748f512ceSopenharmony_ci pid_t wpid; 60848f512ceSopenharmony_ci int childStatus; 60948f512ceSopenharmony_ci bool ret = false; 61048f512ceSopenharmony_ci hperfPid_ = fork(); 61148f512ceSopenharmony_ci if (hperfPid_ == -1) { 61248f512ceSopenharmony_ci char errInfo[ERRINFOLEN] = { 0 }; 61348f512ceSopenharmony_ci strerror_r(errno, errInfo, ERRINFOLEN); 61448f512ceSopenharmony_ci HIPERF_HILOGI(MODULE_CPP_API, "failed to fork: %" HILOG_PUBLIC "s", errInfo); 61548f512ceSopenharmony_ci return false; 61648f512ceSopenharmony_ci } else if (hperfPid_ == 0) { 61748f512ceSopenharmony_ci // child execute 61848f512ceSopenharmony_ci std::vector<std::string> cmd; 61948f512ceSopenharmony_ci GetExecCmd(cmd, args); 62048f512ceSopenharmony_ci ChildRunExecv(cmd); 62148f512ceSopenharmony_ci } else { 62248f512ceSopenharmony_ci ret = ParentWait(wpid, hperfPid_, childStatus); 62348f512ceSopenharmony_ci } 62448f512ceSopenharmony_ci return ret; 62548f512ceSopenharmony_ci} 62648f512ceSopenharmony_ci 62748f512ceSopenharmony_cibool Client::PrePare(const RecordOption &option) 62848f512ceSopenharmony_ci{ 62948f512ceSopenharmony_ci HIPERF_HILOGI(MODULE_CPP_API, "Client:%" HILOG_PUBLIC "s\n", __FUNCTION__); 63048f512ceSopenharmony_ci if (!option.GetOutputFileName().empty()) { 63148f512ceSopenharmony_ci outputFileName_ = option.GetOutputFileName(); 63248f512ceSopenharmony_ci } 63348f512ceSopenharmony_ci return Start(option.GetOptionVecString(), false); 63448f512ceSopenharmony_ci} 63548f512ceSopenharmony_ci 63648f512ceSopenharmony_cibool Client::WaitCommandReply(std::chrono::milliseconds timeOut) 63748f512ceSopenharmony_ci{ 63848f512ceSopenharmony_ci std::string reply; 63948f512ceSopenharmony_ci struct pollfd pollFd; 64048f512ceSopenharmony_ci pollFd.fd = serverToClientFd_; 64148f512ceSopenharmony_ci pollFd.events = POLLIN; 64248f512ceSopenharmony_ci pollFd.revents = 0; 64348f512ceSopenharmony_ci 64448f512ceSopenharmony_ci // wait some data 64548f512ceSopenharmony_ci int polled = poll(&pollFd, 1, timeOut.count()); 64648f512ceSopenharmony_ci if (polled > 0) { 64748f512ceSopenharmony_ci while (true) { 64848f512ceSopenharmony_ci char c; 64948f512ceSopenharmony_ci ssize_t result = TEMP_FAILURE_RETRY(read(serverToClientFd_, &c, 1)); 65048f512ceSopenharmony_ci if (result <= 0) { 65148f512ceSopenharmony_ci HIPERF_HILOGI(MODULE_CPP_API, "read failed from pipe"); 65248f512ceSopenharmony_ci return false; // read fial means not ok 65348f512ceSopenharmony_ci } 65448f512ceSopenharmony_ci 65548f512ceSopenharmony_ci reply.push_back(c); 65648f512ceSopenharmony_ci if (c == '\n') { 65748f512ceSopenharmony_ci break; 65848f512ceSopenharmony_ci } 65948f512ceSopenharmony_ci } 66048f512ceSopenharmony_ci } else if (polled == 0) { 66148f512ceSopenharmony_ci HIPERF_HILOGI(MODULE_CPP_API, "Client:command no response %" HILOG_PUBLIC "" PRIu64 ".\n", 66248f512ceSopenharmony_ci (uint64_t)timeOut.count()); 66348f512ceSopenharmony_ci } else { 66448f512ceSopenharmony_ci HIPERF_HILOGI(MODULE_CPP_API, "Client:command poll failed.\n"); 66548f512ceSopenharmony_ci } 66648f512ceSopenharmony_ci HIPERF_HILOGI(MODULE_CPP_API, "Client:new reply:%" HILOG_PUBLIC "s\n", reply.c_str()); 66748f512ceSopenharmony_ci if (reply == ReplyOK) { 66848f512ceSopenharmony_ci return true; 66948f512ceSopenharmony_ci } else { 67048f512ceSopenharmony_ci return false; 67148f512ceSopenharmony_ci } 67248f512ceSopenharmony_ci} 67348f512ceSopenharmony_ci 67448f512ceSopenharmony_civoid Client::KillChild() 67548f512ceSopenharmony_ci{ 67648f512ceSopenharmony_ci HIPERF_HILOGI(MODULE_CPP_API, "Client:%" HILOG_PUBLIC "s\n", __FUNCTION__); 67748f512ceSopenharmony_ci if (clientToServerFd_ != -1) { 67848f512ceSopenharmony_ci close(clientToServerFd_); 67948f512ceSopenharmony_ci clientToServerFd_ = -1; 68048f512ceSopenharmony_ci } 68148f512ceSopenharmony_ci if (serverToClientFd_ != -1) { 68248f512ceSopenharmony_ci close(serverToClientFd_); 68348f512ceSopenharmony_ci serverToClientFd_ = -1; 68448f512ceSopenharmony_ci } 68548f512ceSopenharmony_ci if (hperfPid_ > 0) { 68648f512ceSopenharmony_ci kill(hperfPid_, SIGKILL); 68748f512ceSopenharmony_ci hperfPid_ = -1; 68848f512ceSopenharmony_ci } 68948f512ceSopenharmony_ci if (hperfPrePid_ > 0) { 69048f512ceSopenharmony_ci pid_t wpid; 69148f512ceSopenharmony_ci int childStatus; 69248f512ceSopenharmony_ci ParentWait(wpid, hperfPrePid_, childStatus); 69348f512ceSopenharmony_ci hperfPrePid_ = -1; 69448f512ceSopenharmony_ci } 69548f512ceSopenharmony_ci} 69648f512ceSopenharmony_ci 69748f512ceSopenharmony_cibool Client::SendCommandAndWait(const std::string &cmd) 69848f512ceSopenharmony_ci{ 69948f512ceSopenharmony_ci if (clientToServerFd_ == -1) { 70048f512ceSopenharmony_ci HIPERF_HILOGI(MODULE_CPP_API, "fd not ready. maybe not called start."); 70148f512ceSopenharmony_ci return false; 70248f512ceSopenharmony_ci } 70348f512ceSopenharmony_ci size_t size = write(clientToServerFd_, cmd.c_str(), cmd.size()); 70448f512ceSopenharmony_ci HIPERF_HILOGI(MODULE_CPP_API, 70548f512ceSopenharmony_ci "Client:%" HILOG_PUBLIC "s -> %" HILOG_PUBLIC "d : %" HILOG_PUBLIC "zd\n", 70648f512ceSopenharmony_ci cmd.c_str(), clientToServerFd_, size); 70748f512ceSopenharmony_ci if (size == cmd.size()) { 70848f512ceSopenharmony_ci return WaitCommandReply(); 70948f512ceSopenharmony_ci } else { 71048f512ceSopenharmony_ci return false; 71148f512ceSopenharmony_ci } 71248f512ceSopenharmony_ci} 71348f512ceSopenharmony_ci 71448f512ceSopenharmony_cibool Client::StartRun() 71548f512ceSopenharmony_ci{ 71648f512ceSopenharmony_ci if (!ready_) { 71748f512ceSopenharmony_ci HIPERF_HILOGI(MODULE_CPP_API, "Client:hiperf not ready.\n"); 71848f512ceSopenharmony_ci return false; 71948f512ceSopenharmony_ci } 72048f512ceSopenharmony_ci HIPERF_HILOGI(MODULE_CPP_API, "Client:%" HILOG_PUBLIC "s\n", __FUNCTION__); 72148f512ceSopenharmony_ci if (SendCommandAndWait(ReplyStart)) { 72248f512ceSopenharmony_ci return true; 72348f512ceSopenharmony_ci } 72448f512ceSopenharmony_ci return false; 72548f512ceSopenharmony_ci} 72648f512ceSopenharmony_ci 72748f512ceSopenharmony_cibool Client::Pause() 72848f512ceSopenharmony_ci{ 72948f512ceSopenharmony_ci if (!ready_) { 73048f512ceSopenharmony_ci HIPERF_HILOGI(MODULE_CPP_API, "Client:hiperf not ready.\n"); 73148f512ceSopenharmony_ci return false; 73248f512ceSopenharmony_ci } 73348f512ceSopenharmony_ci HIPERF_HILOGI(MODULE_CPP_API, "Client:%" HILOG_PUBLIC "s\n", __FUNCTION__); 73448f512ceSopenharmony_ci if (SendCommandAndWait(ReplyPause)) { 73548f512ceSopenharmony_ci return true; 73648f512ceSopenharmony_ci } 73748f512ceSopenharmony_ci return false; 73848f512ceSopenharmony_ci} 73948f512ceSopenharmony_ci 74048f512ceSopenharmony_cibool Client::Resume() 74148f512ceSopenharmony_ci{ 74248f512ceSopenharmony_ci if (!ready_) { 74348f512ceSopenharmony_ci HIPERF_HILOGI(MODULE_CPP_API, "Client:hiperf not ready.\n"); 74448f512ceSopenharmony_ci return false; 74548f512ceSopenharmony_ci } 74648f512ceSopenharmony_ci HIPERF_HILOGI(MODULE_CPP_API, "Client:%" HILOG_PUBLIC "s\n", __FUNCTION__); 74748f512ceSopenharmony_ci if (SendCommandAndWait(ReplyResume)) { 74848f512ceSopenharmony_ci return true; 74948f512ceSopenharmony_ci } 75048f512ceSopenharmony_ci return false; 75148f512ceSopenharmony_ci} 75248f512ceSopenharmony_ci 75348f512ceSopenharmony_cibool Client::Stop() 75448f512ceSopenharmony_ci{ 75548f512ceSopenharmony_ci if (!ready_) { 75648f512ceSopenharmony_ci HIPERF_HILOGI(MODULE_CPP_API, "Client:hiperf not ready.\n"); 75748f512ceSopenharmony_ci return false; 75848f512ceSopenharmony_ci } 75948f512ceSopenharmony_ci HIPERF_HILOGI(MODULE_CPP_API, "Client:%" HILOG_PUBLIC "s\n", __FUNCTION__); 76048f512ceSopenharmony_ci if (SendCommandAndWait(ReplyStop)) { 76148f512ceSopenharmony_ci // wait sampling process exit really 76248f512ceSopenharmony_ci while (SendCommandAndWait(ReplyCheck)) { 76348f512ceSopenharmony_ci std::this_thread::sleep_for(1s); 76448f512ceSopenharmony_ci } 76548f512ceSopenharmony_ci return true; 76648f512ceSopenharmony_ci } 76748f512ceSopenharmony_ci return false; 76848f512ceSopenharmony_ci} 76948f512ceSopenharmony_ci 77048f512ceSopenharmony_civoid Client::EnableHilog() 77148f512ceSopenharmony_ci{ 77248f512ceSopenharmony_ci HIPERF_HILOGI(MODULE_CPP_API, "Client:%" HILOG_PUBLIC "s\n", __FUNCTION__); 77348f512ceSopenharmony_ci hilog_ = true; 77448f512ceSopenharmony_ci} 77548f512ceSopenharmony_ci} // namespace HiperfClient 77648f512ceSopenharmony_ci} // namespace HiPerf 77748f512ceSopenharmony_ci} // namespace Developtools 77848f512ceSopenharmony_ci} // namespace OHOS 779