• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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