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 #include "reclaim_priority_constants.h"
16 #include "memmgr_log.h"
17 #include "xml_helper.h"
18 #include "kill_config.h"
19
20 namespace OHOS {
21 namespace Memory {
22 namespace {
23 const std::string TAG = "KillConfig";
24 const unsigned int KILL_LEVEL_ITEMS__MAX_COUNT = 10;
25 }
26
ClearKillLevelsMap()27 void KillConfig::ClearKillLevelsMap()
28 {
29 killLevelsMap_.clear();
30 }
31
ParseConfig(const xmlNodePtr & rootNodePtr)32 void KillConfig::ParseConfig(const xmlNodePtr &rootNodePtr)
33 {
34 if (!XmlHelper::CheckNode(rootNodePtr) || !XmlHelper::HasChild(rootNodePtr)) {
35 HILOGD("Node exsist:%{public}d,has child node:%{public}d",
36 XmlHelper::CheckNode(rootNodePtr), XmlHelper::HasChild(rootNodePtr));
37 return;
38 }
39 for (xmlNodePtr currNode = rootNodePtr->xmlChildrenNode; currNode != nullptr; currNode = currNode->next) {
40 std::map<std::string, std::string> param;
41 XmlHelper::GetModuleParam(currNode, param);
42 if (!ParseKillLevelNode(currNode, param) || killLevelsMap_.size() > KILL_LEVEL_ITEMS__MAX_COUNT) {
43 /* if has error, clear set */
44 killLevelsMap_.clear();
45 break;
46 }
47 }
48 if (killLevelsMap_.empty()) {
49 return;
50 }
51 /* check if <memoryMB, minPriority> is increasing, if not, invalid. */
52 int lastPriority = RECLAIM_PRIORITY_MIN - 1;
53 for (auto it = killLevelsMap_.begin(); it != killLevelsMap_.end(); it++) {
54 HILOGD("KillConfig: memory:%{public}u prio:%{public}d lastPrio:%{public}d",
55 it->first, it->second, lastPriority);
56 if (it->second <= lastPriority) {
57 /* Priority list must be decreasing, if not, clear set */
58 HILOGE("KillConfig: memory:%{public}u prio:%{public}d invalid", it->first, it->second);
59 killLevelsMap_.clear();
60 break;
61 }
62 lastPriority = it->second;
63 }
64 }
65
GetKillLevelsMap()66 const KillConfig::KillLevelsMap& KillConfig::GetKillLevelsMap()
67 {
68 return killLevelsMap_;
69 }
70
ParseKillLevelNode(const xmlNodePtr & currNodePtr,std::map<std::string,std::string> & param)71 bool KillConfig::ParseKillLevelNode(const xmlNodePtr &currNodePtr,
72 std::map<std::string, std::string> ¶m)
73 {
74 std::string name = std::string(reinterpret_cast<const char *>(currNodePtr->name));
75 if (name.compare("comment") == 0) {
76 HILOGD("%{public}s comment skip :<%{public}s>", __func__, name.c_str());
77 return true;
78 }
79 if (name.compare("killLevel") != 0) {
80 HILOGW("%{public}s unknown node :<%{public}s>", __func__, name.c_str());
81 return false;
82 }
83 unsigned int memoryMB;
84 int minPriority;
85 XmlHelper::SetUnsignedIntParam(param, "memoryMB", memoryMB, 0);
86 XmlHelper::SetIntParam(param, "minPriority", minPriority, RECLAIM_PRIORITY_MAX + 1);
87 /* if read from xml fail, error */
88 if (memoryMB == 0 || minPriority == (RECLAIM_PRIORITY_MAX + 1)) {
89 HILOGE("node:<%{public}s> <%{public}u, %{public}d> read fail", name.c_str(), memoryMB, minPriority);
90 return false;
91 }
92 if ((memoryMB * KB_PER_MB) > UINT_MAX) {
93 HILOGE("<%{public}s> %{public}u MB to KB > UINT_MAX", name.c_str(), memoryMB);
94 return false;
95 }
96 unsigned int memoryKB = memoryMB * KB_PER_MB; /* MB to KB */
97 if (killLevelsMap_.count(memoryKB) > 0) { /* if key @memoryKB has exist, error */
98 HILOGE("node:<%{public}s> <%{public}u, %{public}d> key has exist, mapSize:%{public}zu",
99 name.c_str(), memoryKB, minPriority, killLevelsMap_.size());
100 return false;
101 }
102 killLevelsMap_.insert(std::make_pair(memoryKB, minPriority));
103 return true;
104 }
105
Dump(int fd)106 void KillConfig::Dump(int fd)
107 {
108 dprintf(fd, "KillConfig: \n");
109 for (auto it = killLevelsMap_.begin(); it != killLevelsMap_.end(); it++) {
110 dprintf(fd, " memory:%u ----> prio:%d \n", it->first, it->second);
111 }
112 }
113 } // namespace Memory
114 } // namespace OHOS
115