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 strs[strs.size() - 1] = "reg";
58 for (size_t i = 0; i < strs.size(); i++) {
59 path += "/";
60 path += strs.at(i);
61 }
62 }
63
64 /**
65 * @description: Get value from the string
66 * @param {string} &str:string
67 * @param {string} &result:the value
68 * @return {*}
69 */
GetValue(const std::string & str,uint64_t & value)70 void GetHardwareInfo::GetValue(const std::string &str, uint64_t &value)
71 {
72 value = 0;
73 istringstream ss(str);
74 string word;
75 vector<string> words;
76 while (ss >> word) {
77 words.push_back(word);
78 }
79 if (words.size() >= WORD_SIZE) {
80 string tempWord = words.at(3);
81 StringUtils::GetInstance().HexToDec(tempWord, value);
82 }
83 }
84
RegStrToRegValue(const vector<string> & infos,uint64_t & value)85 bool GetHardwareInfo::RegStrToRegValue(const vector<string> &infos, uint64_t &value)
86 {
87 string tempValueStr = "";
88 vector<string> tempStrs;
89 for (string str : infos) {
90 StringUtils::GetInstance().StringSplit(str, ":", tempStrs);
91 if (tempStrs.size() > 0) {
92 tempValueStr = tempStrs[1];
93 uint64_t tempValue = 0;
94 GetValue(tempValueStr, tempValue);
95 value += tempValue;
96 } else {
97 DUMPER_HILOGE(MODULE_SERVICE, "Hardware Usage fail, get reg value fail .\n");
98 return false;
99 }
100 }
101 return true;
102 }
103
GetResverRegValue(const string & path,uint64_t & value)104 bool GetHardwareInfo::GetResverRegValue(const string &path, uint64_t &value)
105 {
106 string cmd = "xxd -g 4 " + path;
107 vector<string> valueStrs;
108 bool success = MemoryUtil::GetInstance().RunCMD(cmd, valueStrs);
109 if (success) {
110 RegStrToRegValue(valueStrs, value);
111 } else {
112 DUMPER_HILOGE(MODULE_SERVICE, "Hardware Usage fail, get reg value by run cmd fail .\n");
113 return false;
114 }
115 return true;
116 }
117
CalcHardware(const vector<string> & paths)118 uint64_t GetHardwareInfo::CalcHardware(const vector<string> &paths)
119 {
120 uint64_t totalValue = 0;
121 if (paths.size() > 0) {
122 for (string path : paths) {
123 GetResverRegPath(path);
124 if (!path.empty()) {
125 uint64_t value = 0;
126 GetResverRegValue(path, value);
127 totalValue += value;
128 }
129 }
130 }
131 return totalValue;
132 }
133
GetGroupOfPaths(const size_t & index,const size_t & size,const std::vector<std::string> & paths,std::vector<string> & groupPaths)134 void GetHardwareInfo::GetGroupOfPaths(const size_t &index, const size_t &size, const std::vector<std::string> &paths,
135 std::vector<string> &groupPaths)
136 {
137 for (size_t i = index * size; i <= (index + 1) * size - 1; i++) {
138 if (i <= paths.size() - 1) {
139 groupPaths.push_back(paths.at(i));
140 }
141 }
142 }
143
GetHardwareUsage(uint64_t & totalValue)144 bool GetHardwareInfo::GetHardwareUsage(uint64_t &totalValue)
145 {
146 totalValue = 0;
147 vector<string> paths;
148 bool findPathSuccess = FindFilePaths(paths);
149 if (findPathSuccess) {
150 size_t size = paths.size();
151 if (size > 0) {
152 size_t threadNum =
153 MemoryUtil::GetInstance().GetMaxThreadNum(MemoryFilter::GetInstance().HARDWARE_USAGE_THREAD_NUM_);
154 if (threadNum == 0) {
155 threadNum = 1;
156 }
157 size_t groupSize = (size - 1) / threadNum + 1;
158
159 std::vector<future<uint64_t>> results;
160
161 for (size_t i = 0; i < threadNum; i++) {
162 vector<string> groupPaths;
163 GetGroupOfPaths(i, groupSize, paths, groupPaths);
164 auto future = std::async(std::launch::async, CalcHardware, groupPaths);
165 results.emplace_back(std::move(future));
166 }
167
168 for (auto &tempResult : results) {
169 uint64_t value = tempResult.get();
170 totalValue += value;
171 }
172 totalValue = totalValue / MemoryUtil::GetInstance().BYTE_TO_KB_;
173 } else {
174 DUMPER_HILOGD(MODULE_SERVICE, "GetHardwareInfo file path size is 0\n");
175 }
176
177 return true;
178 } else {
179 return false;
180 }
181 }
182 } // namespace HiviewDFX
183 } // namespace OHOS
184