1 /*
2 * Copyright (C) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include <fstream>
16 #include <string>
17 #include <iostream>
18 #include <cctype>
19 #include "include/hiperf.h"
20 #include "include/sp_log.h"
21 #include "include/sp_thread_socket.h"
22 namespace OHOS {
23 namespace SmartPerf {
ItemData()24 std::map<std::string, std::string> Hiperf::ItemData()
25 {
26 std::map<std::string, std::string> result;
27 LOGI("Hiperf:ItemData map size(%u)", result.size());
28 return result;
29 }
30
StartExecutionOnce(bool isPause)31 void Hiperf::StartExecutionOnce(bool isPause)
32 {
33 PrepareHiperf();
34 StartHiperf();
35 }
36
FinishtExecutionOnce(bool isPause)37 void Hiperf::FinishtExecutionOnce(bool isPause)
38 {
39 std::unique_lock<std::mutex> lock(hiperfLock_);
40 StopHiperf();
41 GetHiperfData();
42 }
43
SetProcessId(const std::string & pid)44 void Hiperf::SetProcessId(const std::string &pid)
45 {
46 processId_ = pid;
47 }
48
PrepareHiperf()49 void Hiperf::PrepareHiperf()
50 {
51 std::string cmdResult;
52 const std::string preparedCmd = "hiperf stat --control prepare -p " + processId_ + " -o " + savePath_;
53 SPUtils::LoadCmd(preparedCmd, cmdResult);
54 if (cmdResult.empty()) {
55 LOGE("create control hiperf sampling failed");
56 return;
57 }
58 if (cmdResult.find("success") != std::string::npos) {
59 LOGD("create control hiperf sampling success");
60 return;
61 }
62 if (cmdResult.find("another sampling") != std::string::npos) {
63 LOGD("control hiperf sampling is creatred");
64 return;
65 }
66 }
67
StartHiperf()68 void Hiperf::StartHiperf()
69 {
70 std::string cmdResult;
71 const std::string startCmd = "hiperf stat --control start";
72 SPUtils::LoadCmd(startCmd, cmdResult);
73 if (cmdResult.empty()) {
74 LOGE("hiperf start failed");
75 return;
76 }
77 if (cmdResult.find("success") != std::string::npos) {
78 LOGD("create control hiperf start success");
79 return;
80 }
81 }
82
StopHiperf()83 void Hiperf::StopHiperf()
84 {
85 std::string cmdResult;
86 const std::string stopCmd = "hiperf stat --control stop";
87 SPUtils::LoadCmd(stopCmd, cmdResult);
88 if (cmdResult.empty()) {
89 LOGE("hiperf stop failed");
90 return;
91 }
92 }
93
GetHiperfData()94 void Hiperf::GetHiperfData()
95 {
96 std::string cmdResult;
97 char buf[1024] = {'\0'};
98 const std::string getHiperfFileCmd = "cat " + savePath_;
99 FILE *fd = popen(getHiperfFileCmd.c_str(), "r");
100 if (fd == nullptr) {
101 LOGE("cat hiperf test.txt failed");
102 return;
103 }
104 while (fgets(buf, sizeof(buf), fd) != nullptr) {
105 std::string line = buf;
106 SetDataMap(line);
107 }
108 hiperfFirstCollect_ = false;
109 if (pclose(fd) == -1) {
110 LOGE("Error: Failed to close file");
111 return;
112 }
113 }
114
SetDataMap(std::string & line)115 void Hiperf::SetDataMap(std::string &line)
116 {
117 for (const auto &dataKey : collectNodes_) {
118 if (line.find(dataKey) != std::string::npos) {
119 std::string count;
120 std::stringstream ss(line);
121 ss >> count;
122 count = ProcessCountData(count);
123 if (!hiperfFirstCollect_) {
124 long long newCount = SPUtilesTye::StringToSometype<long long>(hiperfData_[dataKey]) +
125 SPUtilesTye::StringToSometype<long long>(count);
126 hiperfData_[dataKey] = std::to_string(newCount);
127 } else {
128 hiperfData_[dataKey] = count;
129 }
130 }
131 }
132 }
133
ReturnHiperfData()134 std::string Hiperf::ReturnHiperfData()
135 {
136 std::string hiperfStr = "hci$$" + SpThreadSocket::GetInstance().MapToString(hiperfData_);
137 LOGD("Hiperf::hiperfStr = %s", hiperfStr.c_str());
138 return hiperfStr;
139 }
140
ProcessCountData(std::string count)141 std::string Hiperf::ProcessCountData(std::string count)
142 {
143 std::string countStr = "";
144 for (char c : count) {
145 if (!std::ispunct(c)) {
146 countStr += c;
147 }
148 }
149 return countStr;
150 }
151 }
152 }
153