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