1 /*
2 * Copyright (c) 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 #ifndef SOC_PERF_INCLUDE_SOCPERF_COMMON_H
17 #define SOC_PERF_INCLUDE_SOCPERF_COMMON_H
18
19 #include <string>
20 #include <vector>
21 #include <unordered_map>
22 #include <unordered_set>
23 #include "hilog/log.h"
24
25 namespace OHOS {
26 namespace SOCPERF {
27 #define LOG_TAG_SOC_PERF "socperf"
28 #define LOG_TAG_DOMAIN_ID_SOC_PERF 0xD001703
29
30 static constexpr OHOS::HiviewDFX::HiLogLabel SOC_PERF_LOG_LABEL = {
31 LOG_CORE,
32 LOG_TAG_DOMAIN_ID_SOC_PERF,
33 LOG_TAG_SOC_PERF
34 };
35
36 #define SOC_PERF_LOGF(...) (void)OHOS::HiviewDFX::HiLog::Fatal(SOC_PERF_LOG_LABEL, __VA_ARGS__)
37 #define SOC_PERF_LOGE(...) (void)OHOS::HiviewDFX::HiLog::Error(SOC_PERF_LOG_LABEL, __VA_ARGS__)
38 #define SOC_PERF_LOGW(...) (void)OHOS::HiviewDFX::HiLog::Warn(SOC_PERF_LOG_LABEL, __VA_ARGS__)
39 #define SOC_PERF_LOGI(...) (void)OHOS::HiviewDFX::HiLog::Info(SOC_PERF_LOG_LABEL, __VA_ARGS__)
40 #define SOC_PERF_LOGD(...) (void)OHOS::HiviewDFX::HiLog::Debug(SOC_PERF_LOG_LABEL, __VA_ARGS__)
41
42 enum EventType {
43 EVENT_INVALID = -1,
44 EVENT_OFF,
45 EVENT_ON
46 };
47
48 enum ActionType {
49 ACTION_TYPE_PERF,
50 ACTION_TYPE_POWER,
51 ACTION_TYPE_THERMAL,
52 ACTION_TYPE_MAX
53 };
54
55 namespace {
56 const int32_t INNER_EVENT_ID_INIT_RES_NODE_INFO = 0;
57 const int32_t INNER_EVENT_ID_INIT_GOV_RES_NODE_INFO = 1;
58 const int32_t INNER_EVENT_ID_DO_FREQ_ACTION = 2;
59 const int32_t INNER_EVENT_ID_DO_FREQ_ACTION_DELAYED = 3;
60 const int32_t INNER_EVENT_ID_POWER_LIMIT_BOOST_FREQ = 4;
61 const int32_t INNER_EVENT_ID_THERMAL_LIMIT_BOOST_FREQ = 5;
62 }
63
64 namespace {
65 const std::string SOCPERF_RESOURCE_CONFIG_XML = "etc/soc_perf/socperf_resource_config.xml";
66 const std::string SOCPERF_BOOST_CONFIG_XML = "etc/soc_perf/socperf_boost_config.xml";
67 const int64_t MAX_INT_VALUE = 0x7FFFFFFFFFFFFFFF;
68 const int64_t MIN_INT_VALUE = 0x8000000000000000;
69 const int32_t INVALID_VALUE = -1;
70 const int32_t MAX_HANDLER_THREADS = 5;
71 const int32_t MIN_RESOURCE_ID = 1000;
72 const int32_t MAX_RESOURCE_ID = 5999;
73 const int32_t RES_ID_AND_VALUE_PAIR = 2;
74 const int32_t RES_ID_NUMS_PER_TYPE = 1000;
75 }
76
77 class ResNode {
78 public:
79 int32_t id;
80 std::string name;
81 int64_t def;
82 std::string path;
83 int32_t mode;
84 int32_t pair;
85 std::unordered_set<int64_t> available;
86
87 public:
ResNode(int32_t resId,std::string resName,int32_t resMode,int32_t resPair)88 ResNode(int32_t resId, std::string resName, int32_t resMode, int32_t resPair)
89 {
90 id = resId;
91 name = resName;
92 mode = resMode;
93 pair = resPair;
94 def = INVALID_VALUE;
95 }
~ResNode()96 ~ResNode() {}
97
PrintString()98 void PrintString()
99 {
100 SOC_PERF_LOGD("resNode-> id: [%{public}d], name: [%{public}s]", id, name.c_str());
101 SOC_PERF_LOGD(" path: [%{public}s]", path.c_str());
102 SOC_PERF_LOGD(" def: [%{public}lld], mode: [%{public}d], pair: [%{public}d]",
103 (long long)def, mode, pair);
104 std::string str;
105 str.append("available(").append(std::to_string((int32_t)available.size())).append("): ");
106 str.append("[");
107 for (auto validValue : available) {
108 str.append(std::to_string(validValue)).append(",");
109 }
110 if (!available.empty()) {
111 str.pop_back();
112 }
113 str.append("]");
114 SOC_PERF_LOGD(" %{public}s", str.c_str());
115 }
116 };
117
118 class GovResNode {
119 public:
120 int32_t id;
121 std::string name;
122 int64_t def;
123 std::vector<std::string> paths;
124 std::unordered_set<int64_t> available;
125 std::unordered_map<int64_t, std::vector<std::string>> levelToStr;
126
127 public:
GovResNode(int32_t govResId,std::string govResName)128 GovResNode(int32_t govResId, std::string govResName)
129 {
130 id = govResId;
131 name = govResName;
132 def = INVALID_VALUE;
133 }
~GovResNode()134 ~GovResNode() {}
135
PrintString()136 void PrintString()
137 {
138 SOC_PERF_LOGD("govResNode-> id: [%{public}d], name: [%{public}s]", id, name.c_str());
139 SOC_PERF_LOGD(" def: [%{public}lld]", (long long)def);
140 for (auto path : paths) {
141 SOC_PERF_LOGD(" path: [%{public}s]", path.c_str());
142 }
143 std::string str;
144 str.append("available(").append(std::to_string((int32_t)available.size())).append("): ");
145 str.append("[");
146 for (auto validValue : available) {
147 str.append(std::to_string(validValue)).append(",");
148 }
149 if (!available.empty()) {
150 str.pop_back();
151 }
152 str.append("]");
153 SOC_PERF_LOGD(" %{public}s", str.c_str());
154 for (auto iter = levelToStr.begin(); iter != levelToStr.end(); ++iter) {
155 std::string str2;
156 int64_t level = iter->first;
157 std::vector<std::string> result = iter->second;
158 for (int32_t i = 0; i < (int32_t)result.size(); i++) {
159 str2.append(result[i]).append(",");
160 }
161 if (!result.empty()) {
162 str2.pop_back();
163 }
164 SOC_PERF_LOGD(" %{public}lld: [%{public}s]", (long long)level, str2.c_str());
165 }
166 }
167 };
168
169 class Action {
170 public:
171 int32_t duration;
172 std::vector<int64_t> variable;
173
174 public:
Action()175 Action() {}
~Action()176 ~Action() {}
177 };
178
179 class Actions {
180 public:
181 int32_t id;
182 std::string name;
183 std::list<std::shared_ptr<Action>> actionList;
184
185 public:
Actions(int32_t cmdId,std::string cmdName)186 Actions(int32_t cmdId, std::string cmdName)
187 {
188 id = cmdId;
189 name = cmdName;
190 }
~Actions()191 ~Actions() {}
192
PrintString()193 void PrintString()
194 {
195 SOC_PERF_LOGD("Actions-> id: [%{public}d], name: [%{public}s]", id, name.c_str());
196 for (auto iter = actionList.begin(); iter != actionList.end(); iter++) {
197 std::shared_ptr<Action> action = *iter;
198 std::string str;
199 str.append("variable(").append(std::to_string((int32_t)action->variable.size())).append("): [");
200 for (int32_t i = 0; i < (int32_t)action->variable.size(); i++) {
201 str.append(std::to_string(action->variable[i])).append(",");
202 }
203 if (!action->variable.empty()) {
204 str.pop_back();
205 }
206 str.append("]");
207 SOC_PERF_LOGD(" duration: [%{public}d], %{public}s", action->duration, str.c_str());
208 }
209 }
210 };
211
212 class ResAction {
213 public:
214 int64_t value;
215 int32_t duration;
216 int32_t type;
217 int32_t onOff;
218
219 public:
ResAction(int64_t resActionValue,int32_t resActionDuration,int32_t resActionType,int32_t resActionOnOff)220 ResAction(int64_t resActionValue, int32_t resActionDuration, int32_t resActionType, int32_t resActionOnOff)
221 {
222 value = resActionValue;
223 duration = resActionDuration;
224 type = resActionType;
225 onOff = resActionOnOff;
226 }
~ResAction()227 ~ResAction() {}
228
TotalSame(std::shared_ptr<ResAction> resAction)229 bool TotalSame(std::shared_ptr<ResAction> resAction)
230 {
231 if (value == resAction->value
232 && duration == resAction->duration
233 && type == resAction->type
234 && onOff == resAction->onOff) {
235 return true;
236 }
237 return false;
238 }
239
PartSame(std::shared_ptr<ResAction> resAction)240 bool PartSame(std::shared_ptr<ResAction> resAction)
241 {
242 if (value == resAction->value
243 && duration == resAction->duration
244 && type == resAction->type) {
245 return true;
246 }
247 return false;
248 }
249 };
250
251 class ResStatus {
252 public:
253 std::vector<std::list<std::shared_ptr<ResAction>>> resActionList;
254 std::vector<int64_t> candidates;
255 int64_t candidate;
256 int64_t current;
257
258 public:
ResStatus(int64_t val)259 explicit ResStatus(int64_t val)
260 {
261 resActionList = std::vector<std::list<std::shared_ptr<ResAction>>>(ACTION_TYPE_MAX);
262 candidates = std::vector<int64_t>(ACTION_TYPE_MAX);
263 candidates[ACTION_TYPE_PERF] = INVALID_VALUE;
264 candidates[ACTION_TYPE_POWER] = INVALID_VALUE;
265 candidates[ACTION_TYPE_THERMAL] = INVALID_VALUE;
266 candidate = val;
267 current = val;
268 }
~ResStatus()269 ~ResStatus() {}
270
ToString()271 std::string ToString()
272 {
273 std::string str;
274 str.append("perf:[");
275 for (auto iter = resActionList[ACTION_TYPE_PERF].begin();
276 iter != resActionList[ACTION_TYPE_PERF].end(); ++iter) {
277 str.append(std::to_string((*iter)->value)).append(",");
278 }
279 if (!resActionList[ACTION_TYPE_PERF].empty()) {
280 str.pop_back();
281 }
282 str.append("]power:[");
283 for (auto iter = resActionList[ACTION_TYPE_POWER].begin();
284 iter != resActionList[ACTION_TYPE_POWER].end(); ++iter) {
285 str.append(std::to_string((*iter)->value)).append(",");
286 }
287 if (!resActionList[ACTION_TYPE_POWER].empty()) {
288 str.pop_back();
289 }
290 str.append("]thermal:[");
291 for (auto iter = resActionList[ACTION_TYPE_THERMAL].begin();
292 iter != resActionList[ACTION_TYPE_THERMAL].end(); ++iter) {
293 str.append(std::to_string((*iter)->value)).append(",");
294 }
295 if (!resActionList[ACTION_TYPE_THERMAL].empty()) {
296 str.pop_back();
297 }
298 str.append("]candidates[");
299 for (auto iter = candidates.begin(); iter != candidates.end(); ++iter) {
300 str.append(std::to_string(*iter)).append(",");
301 }
302 str.pop_back();
303 str.append("]candidate[").append(std::to_string(candidate));
304 str.append("]current[").append(std::to_string(current)).append("]");
305 return str;
306 }
307 };
308
Max(int64_t num1,int64_t num2)309 static inline int64_t Max(int64_t num1, int64_t num2)
310 {
311 if (num1 >= num2) {
312 return num1;
313 }
314 return num2;
315 }
316
Max(int64_t num1,int64_t num2,int64_t num3)317 static inline int64_t Max(int64_t num1, int64_t num2, int64_t num3)
318 {
319 return Max(Max(num1, num2), num3);
320 }
321
Min(int64_t num1,int64_t num2)322 static inline int64_t Min(int64_t num1, int64_t num2)
323 {
324 if (num1 <= num2) {
325 return num1;
326 }
327 return num2;
328 }
329
Min(int64_t num1,int64_t num2,int64_t num3)330 static inline int64_t Min(int64_t num1, int64_t num2, int64_t num3)
331 {
332 return Min(Min(num1, num2), num3);
333 }
334
IsNumber(std::string str)335 static inline bool IsNumber(std::string str)
336 {
337 for (int32_t i = 0; i < (int32_t)str.size(); i++) {
338 if (i == 0 && str.at(i) == '-') {
339 continue;
340 }
341 if (str.at(i) < '0' || str.at(i) > '9') {
342 return false;
343 }
344 }
345 return true;
346 }
347
IsValidResId(int32_t id)348 static inline bool IsValidResId(int32_t id)
349 {
350 if (id < MIN_RESOURCE_ID || id > MAX_RESOURCE_ID) {
351 return false;
352 }
353 return true;
354 }
355
Split(std::string str,std::string pattern)356 static inline std::vector<std::string> Split(std::string str, std::string pattern)
357 {
358 int32_t position;
359 std::vector<std::string> result;
360 str += pattern;
361 int32_t length = (int32_t)str.size();
362 for (int32_t i = 0; i < length; i++) {
363 position = (int32_t)str.find(pattern, i);
364 if (position < length) {
365 std::string tmp = str.substr(i, position - i);
366 result.push_back(tmp);
367 i = position + (int32_t)pattern.size() - 1;
368 }
369 }
370 return result;
371 }
372 } // namespace SOCPERF
373 } // namespace OHOS
374
375 #endif // SOC_PERF_INCLUDE_SOCPERF_COMMON_H
376