1 /*
2 * Copyright (C) 2021-2022 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
16 #include "executor/memory/get_hardware_info.h"
17 #include <future>
18 #include <sstream>
19 #include <thread>
20 #include "executor/memory/memory_filter.h"
21 #include "executor/memory/memory_util.h"
22 #include "hilog_wrapper.h"
23 #include "util/string_utils.h"
24
25 using namespace std;
26 namespace OHOS {
27 namespace HiviewDFX {
28 constexpr int DATAS_MIN_LEN = 1;
GetHardwareInfo()29 GetHardwareInfo::GetHardwareInfo()
30 {
31 }
~GetHardwareInfo()32 GetHardwareInfo::~GetHardwareInfo()
33 {
34 }
35
36 /**
37 * @description: Find the list of directory that contain the no-map node
38 * @param {vector<string>} &result-A list of directories found
39 * @return {bool}-true:success,false:fail
40 */
FindFilePaths(vector<string> & result)41 bool GetHardwareInfo::FindFilePaths(vector<string> &result)
42 {
43 string cmd = "find /proc/device-tree/ -name \"no-map\"";
44 bool success = MemoryUtil::GetInstance().RunCMD(cmd, result);
45 return success;
46 }
47
48 /**
49 * @description: Get the reg node directory
50 * @param {string} &path-Reg node directory
51 * @return {*}
52 */
GetResverRegPath(string & path)53 void GetHardwareInfo::GetResverRegPath(string &path)
54 {
55 vector<string> strs;
56 StringUtils::GetInstance().StringSplit(path, "/", strs);
57 path = "";
58 if (strs.size() == 0) {
59 return;
60 }
61 strs[strs.size() - 1] = "reg";
62 for (size_t i = 0; i < strs.size(); i++) {
63 path += "/";
64 path += strs.at(i);
65 }
66 }
67
68 /**
69 * @description: Get value from the string
70 * @param {string} &str:string
71 * @param {string} &result:the value
72 * @return {*}
73 */
GetValue(const std::string & str,uint64_t & value)74 void GetHardwareInfo::GetValue(const std::string &str, uint64_t &value)
75 {
76 value = 0;
77 istringstream ss(str);
78 string word;
79 vector<string> words;
80 while (ss >> word) {
81 words.push_back(word);
82 }
83 if (words.size() >= WORD_SIZE) {
84 string tempWord = words.at(3);
85 StringUtils::GetInstance().HexToDec(tempWord, value);
86 }
87 }
88
RegStrToRegValue(const vector<string> & infos,uint64_t & value)89 bool GetHardwareInfo::RegStrToRegValue(const vector<string> &infos, uint64_t &value)
90 {
91 string tempValueStr = "";
92 vector<string> tempStrs;
93 for (string str : infos) {
94 StringUtils::GetInstance().StringSplit(str, ":", tempStrs);
95 if (tempStrs.size() > DATAS_MIN_LEN) {
96 tempValueStr = tempStrs[DATAS_MIN_LEN];
97 uint64_t tempValue = 0;
98 GetValue(tempValueStr, tempValue);
99 value += tempValue;
100 } else {
101 DUMPER_HILOGE(MODULE_SERVICE, "Hardware Usage fail, get reg value fail .\n");
102 return false;
103 }
104 }
105 return true;
106 }
107
GetResverRegValue(const string & path,uint64_t & value)108 bool GetHardwareInfo::GetResverRegValue(const string &path, uint64_t &value)
109 {
110 string cmd = "xxd -g 4 " + path;
111 vector<string> valueStrs;
112 bool success = MemoryUtil::GetInstance().RunCMD(cmd, valueStrs);
113 if (success) {
114 RegStrToRegValue(valueStrs, value);
115 } else {
116 DUMPER_HILOGE(MODULE_SERVICE, "Hardware Usage fail, get reg value by run cmd fail .\n");
117 return false;
118 }
119 return true;
120 }
121
CalcHardware(const vector<string> & paths)122 uint64_t GetHardwareInfo::CalcHardware(const vector<string> &paths)
123 {
124 uint64_t totalValue = 0;
125 if (paths.size() > 0) {
126 for (string path : paths) {
127 GetResverRegPath(path);
128 if (!path.empty()) {
129 uint64_t value = 0;
130 GetResverRegValue(path, value);
131 totalValue += value;
132 }
133 }
134 }
135 return totalValue;
136 }
137
GetGroupOfPaths(const size_t & index,const size_t & size,const std::vector<std::string> & paths,std::vector<string> & groupPaths)138 void GetHardwareInfo::GetGroupOfPaths(const size_t &index, const size_t &size, const std::vector<std::string> &paths,
139 std::vector<string> &groupPaths)
140 {
141 if ((index + 1) * size <= 0) {
142 return;
143 }
144 for (size_t i = index * size; i <= (index + 1) * size - 1; i++) {
145 if (i <= paths.size() - 1) {
146 groupPaths.push_back(paths.at(i));
147 }
148 }
149 }
150
GetHardwareUsage(uint64_t & totalValue)151 bool GetHardwareInfo::GetHardwareUsage(uint64_t &totalValue)
152 {
153 totalValue = 0;
154 vector<string> paths;
155 bool findPathSuccess = FindFilePaths(paths);
156 if (!findPathSuccess) {
157 DUMPER_HILOGE(MODULE_SERVICE, "find hardware path failed.");
158 return false;
159 }
160 size_t size = paths.size();
161 if (size > 0) {
162 size_t threadNum =
163 MemoryUtil::GetInstance().GetMaxThreadNum(MemoryFilter::GetInstance().HARDWARE_USAGE_THREAD_NUM_);
164 if (threadNum == 0) {
165 threadNum = 1;
166 }
167 size_t groupSize = (size - 1) / threadNum + 1;
168 std::vector<future<uint64_t>> results;
169 for (size_t i = 0; i < threadNum; i++) {
170 vector<string> groupPaths;
171 GetGroupOfPaths(i, groupSize, paths, groupPaths);
172 std::promise<uint64_t> promise;
173 std::future<uint64_t> future = promise.get_future();
174 std::thread([promise = std::move(promise), groupPaths]() mutable {
175 promise.set_value(CalcHardware(groupPaths));
176 }).detach();
177 results.emplace_back(std::move(future));
178 }
179 for (auto& tempResult : results) {
180 uint64_t value = tempResult.get();
181 totalValue += value;
182 }
183 totalValue = totalValue / MemoryUtil::GetInstance().BYTE_TO_KB_;
184 } else {
185 DUMPER_HILOGD(MODULE_SERVICE, "GetHardwareInfo file path size is 0\n");
186 }
187 return true;
188 }
189 } // namespace HiviewDFX
190 } // namespace OHOS
191