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