1 /*
2 * Copyright (c) 2022-2024 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 #include <chrono>
16 #include <dlfcn.h>
17 #include "socperf_config.h"
18 #include "config_policy_utils.h"
19 #include "hisysevent.h"
20 #include "hitrace_meter.h"
21 #include "parameters.h"
22 #ifdef RES_SCHED_SA_INIT
23 #include "res_sa_init.h"
24 #endif
25
26 namespace OHOS {
27 namespace SOCPERF {
28 namespace {
29 std::mutex g_resStrToIdMutex;
30 std::unordered_map<std::string, int32_t> g_resStrToIdInfo;
31 void* g_handle;
32 const std::string SPLIT_OR = "|";
33 const std::string SPLIT_EQUAL = "=";
34 const std::string SPLIT_SPACE = " ";
35 }
36
GetInstance()37 SocPerfConfig& SocPerfConfig::GetInstance()
38 {
39 static SocPerfConfig socPerfConfig_;
40 return socPerfConfig_;
41 }
42
SocPerfConfig()43 SocPerfConfig::SocPerfConfig() {}
44
~SocPerfConfig()45 SocPerfConfig::~SocPerfConfig()
46 {
47 if (g_handle != nullptr) {
48 dlclose(g_handle);
49 g_handle = nullptr;
50 }
51 }
52
Init()53 bool SocPerfConfig::Init()
54 {
55 #ifdef RES_SCHED_SA_INIT
56 std::lock_guard<std::mutex> xmlLock(ResourceSchedule::ResSchedSaInit::GetInstance().saInitXmlMutex_);
57 #endif
58 std::string resourceConfigXml = system::GetParameter("ohos.boot.kernel", "").size() > 0 ?
59 SOCPERF_BOOST_CONFIG_XML_EXT : SOCPERF_BOOST_CONFIG_XML;
60 if (!LoadConfigXmlFile(SOCPERF_RESOURCE_CONFIG_XML)) {
61 SOC_PERF_LOGE("Failed to load %{private}s", SOCPERF_RESOURCE_CONFIG_XML.c_str());
62 return false;
63 }
64
65 if (!LoadConfigXmlFile(resourceConfigXml)) {
66 SOC_PERF_LOGE("Failed to load %{private}s", resourceConfigXml.c_str());
67 return false;
68 }
69
70 std::unique_lock<std::mutex> lock(g_resStrToIdMutex);
71 g_resStrToIdInfo.clear();
72 g_resStrToIdInfo = std::unordered_map<std::string, int32_t>();
73 lock.unlock();
74 SOC_PERF_LOGD("SocPerf Init SUCCESS!");
75 return true;
76 }
77
IsGovResId(int32_t resId) const78 bool SocPerfConfig::IsGovResId(int32_t resId) const
79 {
80 auto item = resourceNodeInfo_.find(resId);
81 if (item != resourceNodeInfo_.end() && item->second->isGov) {
82 return true;
83 }
84 return false;
85 }
86
IsValidResId(int32_t resId) const87 bool SocPerfConfig::IsValidResId(int32_t resId) const
88 {
89 if (resourceNodeInfo_.find(resId) == resourceNodeInfo_.end()) {
90 return false;
91 }
92 return true;
93 }
94
GetRealConfigPath(const std::string & configFile)95 std::string SocPerfConfig::GetRealConfigPath(const std::string& configFile)
96 {
97 char buf[PATH_MAX + 1];
98 char* configFilePath = GetOneCfgFile(configFile.c_str(), buf, PATH_MAX + 1);
99 char tmpPath[PATH_MAX + 1] = {0};
100 if (!configFilePath || strlen(configFilePath) == 0 || strlen(configFilePath) > PATH_MAX ||
101 !realpath(configFilePath, tmpPath)) {
102 SOC_PERF_LOGE("load %{private}s file fail", configFile.c_str());
103 return "";
104 }
105 return std::string(tmpPath);
106 }
107
LoadConfigXmlFile(const std::string & configFile)108 bool SocPerfConfig::LoadConfigXmlFile(const std::string& configFile)
109 {
110 std::string realConfigFile = GetRealConfigPath(configFile);
111 if (realConfigFile.size() == 0) {
112 return false;
113 }
114 xmlKeepBlanksDefault(0);
115 xmlDoc* file = xmlReadFile(realConfigFile.c_str(), nullptr, XML_PARSE_NOERROR | XML_PARSE_NOWARNING);
116 if (!file) {
117 SOC_PERF_LOGE("Failed to open xml file");
118 return false;
119 }
120 xmlNode* rootNode = xmlDocGetRootElement(file);
121 if (!rootNode) {
122 SOC_PERF_LOGE("Failed to get xml file's RootNode");
123 xmlFreeDoc(file);
124 return false;
125 }
126 if (!xmlStrcmp(rootNode->name, reinterpret_cast<const xmlChar*>("Configs"))) {
127 if (realConfigFile.find(SOCPERF_RESOURCE_CONFIG_XML) != std::string::npos) {
128 bool ret = ParseResourceXmlFile(rootNode, realConfigFile, file);
129 if (!ret) {
130 xmlFreeDoc(file);
131 return false;
132 }
133 } else {
134 bool ret = ParseBoostXmlFile(rootNode, realConfigFile, file);
135 if (!ret) {
136 xmlFreeDoc(file);
137 return false;
138 }
139 }
140 } else {
141 SOC_PERF_LOGE("Wrong format for xml file");
142 xmlFreeDoc(file);
143 return false;
144 }
145 xmlFreeDoc(file);
146 SOC_PERF_LOGD("Success to Load %{private}s", configFile.c_str());
147 return true;
148 }
149
InitPerfFunc(const char * perfSoPath,const char * perfSoFunc)150 void SocPerfConfig::InitPerfFunc(const char* perfSoPath, const char* perfSoFunc)
151 {
152 if (perfSoPath == nullptr || perfSoFunc == nullptr) {
153 return;
154 }
155
156 g_handle = dlopen(perfSoPath, RTLD_NOW);
157 if (g_handle == nullptr) {
158 SOC_PERF_LOGE("perf so doesn't exist");
159 return;
160 }
161
162 reportFunc_ = reinterpret_cast<ReportDataFunc>(dlsym(g_handle, perfSoFunc));
163 if (reportFunc_ == nullptr) {
164 SOC_PERF_LOGE("perf func doesn't exist");
165 dlclose(g_handle);
166 }
167 }
168
ParseBoostXmlFile(const xmlNode * rootNode,const std::string & realConfigFile,xmlDoc * file)169 bool SocPerfConfig::ParseBoostXmlFile(const xmlNode* rootNode, const std::string& realConfigFile, xmlDoc* file)
170 {
171 if (!LoadCmd(rootNode, realConfigFile)) {
172 return false;
173 }
174 return true;
175 }
176
ParseResourceXmlFile(const xmlNode * rootNode,const std::string & realConfigFile,xmlDoc * file)177 bool SocPerfConfig::ParseResourceXmlFile(const xmlNode* rootNode, const std::string& realConfigFile, xmlDoc* file)
178 {
179 xmlNode* child = rootNode->children;
180 for (; child; child = child->next) {
181 if (!xmlStrcmp(child->name, reinterpret_cast<const xmlChar*>("Resource"))) {
182 if (!LoadResource(child, realConfigFile)) {
183 return false;
184 }
185 } else if (!xmlStrcmp(child->name, reinterpret_cast<const xmlChar*>("GovResource"))) {
186 if (!LoadGovResource(child, realConfigFile)) {
187 return false;
188 }
189 } else if (!xmlStrcmp(child->name, reinterpret_cast<const xmlChar*>("Info"))) {
190 LoadInfo(child, realConfigFile);
191 }
192 }
193 return true;
194 }
195
LoadResource(xmlNode * child,const std::string & configFile)196 bool SocPerfConfig::LoadResource(xmlNode* child, const std::string& configFile)
197 {
198 xmlNode* grandson = child->children;
199 for (; grandson; grandson = grandson->next) {
200 if (!xmlStrcmp(grandson->name, reinterpret_cast<const xmlChar*>("res"))) {
201 if (!TraversalFreqResource(grandson, configFile)) {
202 return false;
203 }
204 }
205 }
206
207 if (!CheckPairResIdValid() || !CheckDefValid()) {
208 return false;
209 }
210
211 return true;
212 }
213
TraversalFreqResource(xmlNode * grandson,const std::string & configFile)214 bool SocPerfConfig::TraversalFreqResource(xmlNode* grandson, const std::string& configFile)
215 {
216 char* id = reinterpret_cast<char*>(xmlGetProp(grandson, reinterpret_cast<const xmlChar*>("id")));
217 char* name = reinterpret_cast<char*>(xmlGetProp(grandson, reinterpret_cast<const xmlChar*>("name")));
218 char* pair = reinterpret_cast<char*>(xmlGetProp(grandson, reinterpret_cast<const xmlChar*>("pair")));
219 char* mode = reinterpret_cast<char*>(xmlGetProp(grandson, reinterpret_cast<const xmlChar*>("mode")));
220 char* persistMode = reinterpret_cast<char*>(xmlGetProp(grandson, reinterpret_cast<const xmlChar*>("switch")));
221 if (!CheckResourceTag(id, name, pair, mode, persistMode, configFile)) {
222 xmlFree(id);
223 xmlFree(name);
224 xmlFree(pair);
225 xmlFree(mode);
226 xmlFree(persistMode);
227 return false;
228 }
229 xmlNode* greatGrandson = grandson->children;
230 std::shared_ptr<ResNode> resNode = std::make_shared<ResNode>(atoi(id), name, mode ? atoi(mode) : 0,
231 pair ? atoi(pair) : INVALID_VALUE, persistMode ? atoi(persistMode) : 0);
232 xmlFree(id);
233 xmlFree(name);
234 xmlFree(pair);
235 xmlFree(mode);
236 if (!LoadFreqResourceContent(persistMode ? atoi(persistMode) : 0, greatGrandson, configFile, resNode)) {
237 xmlFree(persistMode);
238 return false;
239 }
240 xmlFree(persistMode);
241 return true;
242 }
243
LoadFreqResourceContent(int32_t persistMode,xmlNode * greatGrandson,const std::string & configFile,std::shared_ptr<ResNode> resNode)244 bool SocPerfConfig::LoadFreqResourceContent(int32_t persistMode, xmlNode* greatGrandson, const std::string& configFile,
245 std::shared_ptr<ResNode> resNode)
246 {
247 char *def = nullptr;
248 char *path = nullptr;
249 char *node = nullptr;
250 for (; greatGrandson; greatGrandson = greatGrandson->next) {
251 if (!xmlStrcmp(greatGrandson->name, reinterpret_cast<const xmlChar*>("default"))) {
252 xmlFree(def);
253 def = reinterpret_cast<char*>(xmlNodeGetContent(greatGrandson));
254 } else if (persistMode != REPORT_TO_PERFSO &&
255 !xmlStrcmp(greatGrandson->name, reinterpret_cast<const xmlChar*>("path"))) {
256 xmlFree(path);
257 path = reinterpret_cast<char*>(xmlNodeGetContent(greatGrandson));
258 } else if (!xmlStrcmp(greatGrandson->name, reinterpret_cast<const xmlChar*>("node"))) {
259 xmlFree(node);
260 node = reinterpret_cast<char*>(xmlNodeGetContent(greatGrandson));
261 }
262 }
263 if (!CheckResourceTag(persistMode, def, path, configFile)) {
264 xmlFree(def);
265 xmlFree(path);
266 xmlFree(node);
267 return false;
268 }
269 resNode->def = atoll(def);
270 if (persistMode != REPORT_TO_PERFSO) {
271 resNode->path = path;
272 }
273 xmlFree(def);
274 xmlFree(path);
275 if (node && !LoadResourceAvailable(resNode, node)) {
276 SOC_PERF_LOGE("Invalid resource node for %{private}s", configFile.c_str());
277 xmlFree(node);
278 return false;
279 }
280 xmlFree(node);
281
282 std::unique_lock<std::mutex> lock(g_resStrToIdMutex);
283 g_resStrToIdInfo.insert(std::pair<std::string, int32_t>(resNode->name, resNode->id));
284 lock.unlock();
285
286 std::unique_lock<std::mutex> lockResourceNode(resourceNodeMutex_);
287 resourceNodeInfo_.insert(std::pair<int32_t, std::shared_ptr<ResNode>>(resNode->id, resNode));
288 lockResourceNode.unlock();
289
290 return true;
291 }
292
LoadGovResource(xmlNode * child,const std::string & configFile)293 bool SocPerfConfig::LoadGovResource(xmlNode* child, const std::string& configFile)
294 {
295 xmlNode* grandson = child->children;
296 for (; grandson; grandson = grandson->next) {
297 if (xmlStrcmp(grandson->name, reinterpret_cast<const xmlChar*>("res"))) {
298 continue;
299 }
300 char* id = reinterpret_cast<char*>(xmlGetProp(grandson, reinterpret_cast<const xmlChar*>("id")));
301 char* name = reinterpret_cast<char*>(xmlGetProp(grandson, reinterpret_cast<const xmlChar*>("name")));
302 char* persistMode = reinterpret_cast<char*>(xmlGetProp(grandson,
303 reinterpret_cast<const xmlChar*>("switch")));
304 if (!CheckGovResourceTag(id, name, persistMode, configFile)) {
305 xmlFree(id);
306 xmlFree(name);
307 xmlFree(persistMode);
308 return false;
309 }
310 xmlNode* greatGrandson = grandson->children;
311 std::shared_ptr<GovResNode> govResNode = std::make_shared<GovResNode>(atoi(id),
312 name, persistMode ? atoi(persistMode) : 0);
313 xmlFree(id);
314 xmlFree(name);
315
316 std::unique_lock<std::mutex> lock(g_resStrToIdMutex);
317 g_resStrToIdInfo.insert(std::pair<std::string, int32_t>(govResNode->name, govResNode->id));
318 lock.unlock();
319
320 std::unique_lock<std::mutex> lockResourceNode(resourceNodeMutex_);
321 resourceNodeInfo_.insert(std::pair<int32_t, std::shared_ptr<GovResNode>>(govResNode->id, govResNode));
322 lockResourceNode.unlock();
323
324 if (!TraversalGovResource(persistMode ? atoi(persistMode) : 0, greatGrandson, configFile, govResNode)) {
325 xmlFree(persistMode);
326 return false;
327 }
328 xmlFree(persistMode);
329 }
330
331 if (!CheckDefValid()) {
332 return false;
333 }
334
335 return true;
336 }
337
LoadInfo(xmlNode * child,const std::string & configFile)338 void SocPerfConfig::LoadInfo(xmlNode* child, const std::string& configFile)
339 {
340 xmlNode* grandson = child->children;
341 if (!grandson || xmlStrcmp(grandson->name, reinterpret_cast<const xmlChar*>("inf"))) {
342 return;
343 }
344 char* perfSoPath = reinterpret_cast<char*>(xmlGetProp(grandson, reinterpret_cast<const xmlChar*>("path")));
345 char* perfSoFunc = reinterpret_cast<char*>(xmlGetProp(grandson, reinterpret_cast<const xmlChar*>("func")));
346 InitPerfFunc(perfSoPath, perfSoFunc);
347 xmlFree(perfSoPath);
348 xmlFree(perfSoFunc);
349 }
350
TraversalGovResource(int32_t persistMode,xmlNode * greatGrandson,const std::string & configFile,std::shared_ptr<GovResNode> govResNode)351 bool SocPerfConfig::TraversalGovResource(int32_t persistMode, xmlNode* greatGrandson, const std::string& configFile,
352 std::shared_ptr<GovResNode> govResNode)
353 {
354 for (; greatGrandson; greatGrandson = greatGrandson->next) {
355 if (!xmlStrcmp(greatGrandson->name, reinterpret_cast<const xmlChar*>("default"))) {
356 char* def = reinterpret_cast<char*>(xmlNodeGetContent(greatGrandson));
357 if (!def || !IsNumber(def)) {
358 SOC_PERF_LOGE("Invalid governor resource default for %{private}s", configFile.c_str());
359 xmlFree(def);
360 return false;
361 }
362 govResNode->def = atoll(def);
363 xmlFree(def);
364 } else if (persistMode != REPORT_TO_PERFSO &&
365 !xmlStrcmp(greatGrandson->name, reinterpret_cast<const xmlChar*>("path"))) {
366 char* path = reinterpret_cast<char*>(xmlNodeGetContent(greatGrandson));
367 if (!path) {
368 SOC_PERF_LOGE("Invalid governor resource path for %{private}s", configFile.c_str());
369 return false;
370 }
371 govResNode->paths.push_back(path);
372 xmlFree(path);
373 } else if (persistMode != REPORT_TO_PERFSO &&
374 !xmlStrcmp(greatGrandson->name, reinterpret_cast<const xmlChar*>("node"))) {
375 char* level = reinterpret_cast<char*>(
376 xmlGetProp(greatGrandson, reinterpret_cast<const xmlChar*>("level")));
377 char* node = reinterpret_cast<char*>(xmlNodeGetContent(greatGrandson));
378 if (!level || !IsNumber(level) || !node
379 || !LoadGovResourceAvailable(govResNode, level, node)) {
380 SOC_PERF_LOGE("Invalid governor resource node for %{private}s", configFile.c_str());
381 xmlFree(level);
382 xmlFree(node);
383 return false;
384 }
385 xmlFree(level);
386 xmlFree(node);
387 }
388 }
389 return true;
390 }
391
LoadCmd(const xmlNode * rootNode,const std::string & configFile)392 bool SocPerfConfig::LoadCmd(const xmlNode* rootNode, const std::string& configFile)
393 {
394 xmlNode* child = rootNode->children;
395 for (; child; child = child->next) { // Iterate all cmdID
396 if (xmlStrcmp(child->name, reinterpret_cast<const xmlChar*>("cmd"))) {
397 continue;
398 }
399 char* id = reinterpret_cast<char*>(xmlGetProp(child, reinterpret_cast<const xmlChar*>("id")));
400 char* name = reinterpret_cast<char*>(xmlGetProp(child, reinterpret_cast<const xmlChar*>("name")));
401 if (!CheckCmdTag(id, name, configFile)) {
402 xmlFree(id);
403 xmlFree(name);
404 return false;
405 }
406 xmlNode* grandson = child->children;
407 std::shared_ptr<Actions> actions = std::make_shared<Actions>(atoi(id), name);
408 xmlFree(id);
409 xmlFree(name);
410
411 char* mode = reinterpret_cast<char*>(xmlGetProp(child, reinterpret_cast<const xmlChar*>("mode")));
412 if (mode) {
413 ParseModeCmd(mode, configFile, actions);
414 xmlFree(mode);
415 }
416
417 if (!TraversalBoostResource(grandson, configFile, actions)) {
418 return false;
419 }
420 std::unique_lock<std::mutex> lockPerfActions(perfActionsMutex_);
421 perfActionsInfo_.insert(std::pair<int32_t, std::shared_ptr<Actions>>(actions->id, actions));
422 lockPerfActions.unlock();
423 }
424
425 if (!CheckActionResIdAndValueValid(configFile)) {
426 return false;
427 }
428
429 return true;
430 }
431
ParseModeCmd(const char * mode,const std::string & configFile,std::shared_ptr<Actions> actions)432 void SocPerfConfig::ParseModeCmd(const char* mode, const std::string& configFile, std::shared_ptr<Actions> actions)
433 {
434 if (!mode) {
435 return;
436 }
437
438 std::string modeStr = mode;
439 std::vector<std::string> modeListResult = Split(modeStr, SPLIT_OR);
440 for (auto pairStr : modeListResult) {
441 std::vector<std::string> itemPair = Split(pairStr, SPLIT_EQUAL);
442 if (itemPair.size() != RES_MODE_AND_ID_PAIR) {
443 SOC_PERF_LOGW("Invaild device mode pair for %{private}s", configFile.c_str());
444 continue;
445 }
446
447 std::string modeDeviceStr = itemPair[0];
448 std::string modeCmdIdStr = itemPair[RES_MODE_AND_ID_PAIR -1];
449 if (modeDeviceStr.empty() || !IsNumber(modeCmdIdStr)) {
450 SOC_PERF_LOGW("Invaild device mode name for %{private}s", configFile.c_str());
451 continue;
452 }
453
454 int32_t cmdId = atoi(modeCmdIdStr.c_str());
455 auto iter = actions->modeMap.find(modeDeviceStr);
456 if (iter != actions->modeMap.end()) {
457 iter->second = cmdId;
458 } else {
459 std::unique_lock<std::mutex> lockModeMap(actions->modeMapMutex_);
460 actions->modeMap.insert(std::pair<std::string, int32_t>(modeDeviceStr, cmdId));
461 lockModeMap.unlock();
462 }
463 }
464 }
465
ParseDuration(xmlNode * greatGrandson,const std::string & configFile,std::shared_ptr<Action> action) const466 bool SocPerfConfig::ParseDuration(xmlNode *greatGrandson,
467 const std::string& configFile, std::shared_ptr<Action> action) const
468 {
469 if (xmlStrcmp(greatGrandson->name, reinterpret_cast<const xmlChar*>("duration"))) {
470 return true;
471 }
472 char* duration = reinterpret_cast<char*>(xmlNodeGetContent(greatGrandson));
473 if (!duration || !IsNumber(duration)) {
474 SOC_PERF_LOGE("Invalid cmd duration for %{private}s", configFile.c_str());
475 xmlFree(duration);
476 return false;
477 }
478 action->duration = atoi(duration);
479 xmlFree(duration);
480 return true;
481 }
482
ParseResValue(xmlNode * greatGrandson,const std::string & configFile,std::shared_ptr<Action> action)483 bool SocPerfConfig::ParseResValue(xmlNode* greatGrandson, const std::string& configFile, std::shared_ptr<Action> action)
484 {
485 if (!xmlStrcmp(greatGrandson->name, reinterpret_cast<const xmlChar*>("duration"))) {
486 return true;
487 }
488 char* resStr = reinterpret_cast<char*>(const_cast<xmlChar*>(greatGrandson->name));
489 char* resValue = reinterpret_cast<char*>(xmlNodeGetContent(greatGrandson));
490 if (!resStr || g_resStrToIdInfo.find(resStr) == g_resStrToIdInfo.end()
491 || !resValue || !IsNumber(resValue)) {
492 SOC_PERF_LOGE("Invalid cmd resource(%{public}s) for %{private}s", resStr, configFile.c_str());
493 xmlFree(resValue);
494 return false;
495 }
496 action->variable.push_back(g_resStrToIdInfo[resStr]);
497 action->variable.push_back(atoll(resValue));
498 xmlFree(resValue);
499 return true;
500 }
501
GetXmlIntProp(const xmlNode * xmlNode,const char * propName) const502 int32_t SocPerfConfig::GetXmlIntProp(const xmlNode* xmlNode, const char* propName) const
503 {
504 int ret = -1;
505 char* propValue = reinterpret_cast<char*>(xmlGetProp(xmlNode, reinterpret_cast<const xmlChar*>(propName)));
506 if (propValue != nullptr && IsNumber(propValue)) {
507 ret = atoi(propValue);
508 }
509 if (propValue != nullptr) {
510 xmlFree(propValue);
511 }
512 return ret;
513 }
514
TraversalBoostResource(xmlNode * grandson,const std::string & configFile,std::shared_ptr<Actions> actions)515 bool SocPerfConfig::TraversalBoostResource(xmlNode* grandson,
516 const std::string& configFile, std::shared_ptr<Actions> actions)
517 {
518 for (; grandson; grandson = grandson->next) { // Iterate all Action
519 std::shared_ptr<Action> action = std::make_shared<Action>();
520 action->thermalLvl_ = GetXmlIntProp(grandson, "thermalLvl");
521 action->thermalCmdId_ = GetXmlIntProp(grandson, "thermalCmdId");
522 xmlNode* greatGrandson = grandson->children;
523 for (; greatGrandson; greatGrandson = greatGrandson->next) { // Iterate duration and all res
524 bool ret = ParseDuration(greatGrandson, configFile, action);
525 if (!ret) {
526 return false;
527 }
528 if (action->duration == 0) {
529 actions->isLongTimePerf = true;
530 }
531 ret = ParseResValue(greatGrandson, configFile, action);
532 if (!ret) {
533 return false;
534 }
535 }
536 actions->actionList.push_back(action);
537 }
538 return true;
539 }
540
CheckResourceTag(const char * id,const char * name,const char * pair,const char * mode,const char * persistMode,const std::string & configFile) const541 bool SocPerfConfig::CheckResourceTag(const char* id, const char* name, const char* pair, const char* mode,
542 const char* persistMode, const std::string& configFile) const
543 {
544 if (!id || !IsNumber(id) || !IsValidRangeResId(atoi(id))) {
545 SOC_PERF_LOGE("Invalid resource id for %{private}s", configFile.c_str());
546 return false;
547 }
548 if (!name) {
549 SOC_PERF_LOGE("Invalid resource name for %{private}s", configFile.c_str());
550 return false;
551 }
552 if (pair && (!IsNumber(pair) || !IsValidRangeResId(atoi(pair)))) {
553 SOC_PERF_LOGE("Invalid resource pair for %{private}s", configFile.c_str());
554 return false;
555 }
556 if (mode && !IsNumber(mode)) {
557 SOC_PERF_LOGE("Invalid resource mode for %{private}s", configFile.c_str());
558 return false;
559 }
560 return CheckResourcePersistMode(persistMode, configFile);
561 }
562
CheckResourcePersistMode(const char * persistMode,const std::string & configFile) const563 bool SocPerfConfig::CheckResourcePersistMode(const char* persistMode, const std::string& configFile) const
564 {
565 if (persistMode && (!IsNumber(persistMode) || !IsValidPersistMode(atoi(persistMode)))) {
566 SOC_PERF_LOGE("Invalid resource persistMode for %{private}s", configFile.c_str());
567 return false;
568 }
569 return true;
570 }
571
CheckResourceTag(int32_t persistMode,const char * def,const char * path,const std::string & configFile) const572 bool SocPerfConfig::CheckResourceTag(int32_t persistMode, const char* def,
573 const char* path, const std::string& configFile) const
574 {
575 if (!def || !IsNumber(def)) {
576 SOC_PERF_LOGE("Invalid resource default for %{private}s", configFile.c_str());
577 return false;
578 }
579 if (persistMode != REPORT_TO_PERFSO && !path) {
580 SOC_PERF_LOGE("Invalid resource path for %{private}s", configFile.c_str());
581 return false;
582 }
583 return true;
584 }
585
LoadResourceAvailable(std::shared_ptr<ResNode> resNode,const char * node)586 bool SocPerfConfig::LoadResourceAvailable(std::shared_ptr<ResNode> resNode, const char* node)
587 {
588 std::string nodeStr = node;
589 std::vector<std::string> result = Split(nodeStr, SPLIT_SPACE);
590 for (auto str : result) {
591 if (IsNumber(str)) {
592 resNode->available.insert(stoll(str));
593 } else {
594 return false;
595 }
596 }
597 return true;
598 }
599
CheckPairResIdValid() const600 bool SocPerfConfig::CheckPairResIdValid() const
601 {
602 for (auto iter = resourceNodeInfo_.begin(); iter != resourceNodeInfo_.end(); ++iter) {
603 if (iter->second->isGov) {
604 continue;
605 }
606 int32_t resId = iter->first;
607 std::shared_ptr<ResNode> resNode = std::static_pointer_cast<ResNode>(iter->second);
608 int32_t pairResId = resNode->pair;
609 if (pairResId != INVALID_VALUE && resourceNodeInfo_.find(pairResId) == resourceNodeInfo_.end()) {
610 SOC_PERF_LOGE("resId[%{public}d]'s pairResId[%{public}d] is not valid", resId, pairResId);
611 return false;
612 }
613 }
614 return true;
615 }
616
CheckDefValid() const617 bool SocPerfConfig::CheckDefValid() const
618 {
619 for (auto iter = resourceNodeInfo_.begin(); iter != resourceNodeInfo_.end(); ++iter) {
620 int32_t resId = iter->first;
621 std::shared_ptr<ResourceNode> resourceNode = iter->second;
622 int64_t def = resourceNode->def;
623 if (!resourceNode->available.empty() && resourceNode->available.find(def) == resourceNode->available.end()) {
624 SOC_PERF_LOGE("resId[%{public}d]'s def[%{public}lld] is not valid", resId, (long long)def);
625 return false;
626 }
627 }
628 return true;
629 }
630
CheckGovResourceTag(const char * id,const char * name,const char * persistMode,const std::string & configFile) const631 bool SocPerfConfig::CheckGovResourceTag(const char* id, const char* name,
632 const char* persistMode, const std::string& configFile) const
633 {
634 if (!id || !IsNumber(id) || !IsValidRangeResId(atoi(id))) {
635 SOC_PERF_LOGE("Invalid governor resource id for %{private}s", configFile.c_str());
636 return false;
637 }
638 if (!name) {
639 SOC_PERF_LOGE("Invalid governor resource name for %{private}s", configFile.c_str());
640 return false;
641 }
642 if (persistMode && (!IsNumber(persistMode) || !IsValidPersistMode(atoi(persistMode)))) {
643 SOC_PERF_LOGE("Invalid governor resource persistMode for %{private}s", configFile.c_str());
644 return false;
645 }
646 return true;
647 }
648
LoadGovResourceAvailable(std::shared_ptr<GovResNode> govResNode,const char * level,const char * node)649 bool SocPerfConfig::LoadGovResourceAvailable(std::shared_ptr<GovResNode> govResNode,
650 const char* level, const char* node)
651 {
652 govResNode->available.insert(atoll(level));
653 std::string nodeStr = node;
654 std::vector<std::string> result = Split(nodeStr, SPLIT_OR);
655 if (result.size() != govResNode->paths.size()) {
656 SOC_PERF_LOGE("Invalid governor resource node matches paths");
657 return false;
658 }
659 std::unique_lock<std::mutex> levelMutex(govResNode->levelToStrMutex_);
660 govResNode->levelToStr.insert(std::pair<int32_t, std::vector<std::string>>(atoll(level), result));
661 levelMutex.unlock();
662 return true;
663 }
664
CheckCmdTag(const char * id,const char * name,const std::string & configFile) const665 bool SocPerfConfig::CheckCmdTag(const char* id, const char* name, const std::string& configFile) const
666 {
667 if (!id || !IsNumber(id)) {
668 SOC_PERF_LOGE("Invalid cmd id for %{private}s", configFile.c_str());
669 return false;
670 }
671 if (!name) {
672 SOC_PERF_LOGE("Invalid cmd name for %{private}s", configFile.c_str());
673 return false;
674 }
675 return true;
676 }
677
TraversalActions(std::shared_ptr<Action> action,int32_t actionId)678 bool SocPerfConfig::TraversalActions(std::shared_ptr<Action> action, int32_t actionId)
679 {
680 for (int32_t i = 0; i < (int32_t)action->variable.size() - 1; i += RES_ID_AND_VALUE_PAIR) {
681 int32_t resId = action->variable[i];
682 int64_t resValue = action->variable[i + 1];
683 if (resourceNodeInfo_.find(resId) != resourceNodeInfo_.end()) {
684 if (resourceNodeInfo_[resId]->persistMode != REPORT_TO_PERFSO &&
685 !resourceNodeInfo_[resId]->available.empty() &&
686 resourceNodeInfo_[resId]->available.find(resValue) == resourceNodeInfo_[resId]->available.end()) {
687 SOC_PERF_LOGE("action[%{public}d]'s resValue[%{public}lld] is not valid",
688 actionId, (long long)resValue);
689 return false;
690 }
691 } else {
692 SOC_PERF_LOGE("action[%{public}d]'s resId[%{public}d] is not valid", actionId, resId);
693 return false;
694 }
695 }
696 return true;
697 }
698
CheckActionResIdAndValueValid(const std::string & configFile)699 bool SocPerfConfig::CheckActionResIdAndValueValid(const std::string& configFile)
700 {
701 std::unordered_map<int32_t, std::shared_ptr<Actions>> actionsInfo = perfActionsInfo_;
702 for (auto actionsIter = actionsInfo.begin(); actionsIter != actionsInfo.end(); ++actionsIter) {
703 int32_t actionId = actionsIter->first;
704 std::shared_ptr<Actions> actions = actionsIter->second;
705 for (auto actionIter = actions->actionList.begin(); actionIter != actions->actionList.end(); ++actionIter) {
706 bool ret = TraversalActions(*actionIter, actionId);
707 if (!ret) {
708 return false;
709 }
710 }
711 }
712 return true;
713 }
714 } // namespace SOCPERF
715 } // namespace OHOS
716