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
17 #include "avail_buffer_manager.h"
18 #include "memmgr_config_manager.h"
19 #include "memmgr_log.h"
20 #include "reclaim_strategy_constants.h"
21 #include "reclaim_strategy_manager.h"
22
23 namespace OHOS {
24 namespace Memory {
25 namespace {
26 const std::string TAG = "ReclaimStrategyManager";
27 }
28
29 IMPLEMENT_SINGLE_INSTANCE(ReclaimStrategyManager);
30
ReclaimStrategyManager()31 ReclaimStrategyManager::ReclaimStrategyManager()
32 {
33 }
34
Init()35 bool ReclaimStrategyManager::Init()
36 {
37 initialized_ = false;
38 do {
39 if (!GetEventHandler_()) {
40 break;
41 }
42 MemmgrConfigManager::GetInstance().Init();
43 AvailBufferManager::GetInstance().Init();
44 if (!MemcgMgr::GetInstance().SetRootMemcgPara()) {
45 break;
46 }
47 initialized_ = true;
48 } while (0);
49
50 if (initialized_) {
51 HILOGI("init successed");
52 } else {
53 HILOGE("init failed");
54 }
55 return initialized_;
56 }
57
GetEventHandler_()58 bool ReclaimStrategyManager::GetEventHandler_()
59 {
60 if (handler_ == nullptr) {
61 handler_ = std::make_shared<AppExecFwk::EventHandler>(AppExecFwk::EventRunner::Create());
62 }
63 if (handler_ == nullptr) {
64 HILOGE("handler init failed");
65 return false;
66 }
67 return true;
68 }
69
NotifyAppStateChanged(std::shared_ptr<ReclaimParam> reclaimPara)70 void ReclaimStrategyManager::NotifyAppStateChanged(std::shared_ptr<ReclaimParam> reclaimPara)
71 {
72 if (!Initailized()) {
73 HILOGE("has not been initialized_, skiped!");
74 return;
75 }
76 std::function<bool()> func = std::bind(
77 &ReclaimStrategyManager::HandleAppStateChanged_, this, reclaimPara);
78 handler_->PostImmediateTask(func);
79 }
80
HandleAppStateChanged_(std::shared_ptr<ReclaimParam> reclaimPara)81 bool ReclaimStrategyManager::HandleAppStateChanged_(std::shared_ptr<ReclaimParam> reclaimPara)
82 {
83 if (reclaimPara == nullptr) {
84 HILOGE("reclaimPara nullptr");
85 return false;
86 }
87 if (reclaimPara->accountId_ < VALID_USER_ID_MIN) {
88 HILOGE("invalid userId %{public}d, less than MIN_VALUE(%{public}d)",
89 reclaimPara->accountId_, VALID_USER_ID_MIN);
90 return false;
91 }
92 HILOGI("%{public}s", reclaimPara->ToString().c_str());
93 bool ret = false;
94 bool (ReclaimStrategyManager::*funcPtr)(std::shared_ptr<ReclaimParam>) = nullptr;
95 switch (reclaimPara->action_) {
96 case AppAction::CREATE_PROCESS_AND_APP:
97 case AppAction::CREATE_PROCESS_ONLY: {
98 funcPtr = &ReclaimStrategyManager::HandleProcessCreate_;
99 break;
100 }
101 case AppAction::APP_DIED:
102 case AppAction::APP_FOREGROUND:
103 case AppAction::APP_BACKGROUND:
104 case AppAction::OTHERS: {
105 HILOGI("others app action! %{public}s", ReclaimParam::GetAppActionStr(reclaimPara->action_).c_str());
106 break;
107 }
108 default:
109 break;
110 }
111 if (funcPtr != nullptr) {
112 ret = (this->*funcPtr)(reclaimPara);
113 }
114 reclaimPara.reset();
115 return ret;
116 }
117
HandleProcessCreate_(std::shared_ptr<ReclaimParam> reclaimPara)118 bool ReclaimStrategyManager::HandleProcessCreate_(std::shared_ptr<ReclaimParam> reclaimPara)
119 {
120 bool ret = MemcgMgr::GetInstance().AddProcToMemcg(reclaimPara->pid_, reclaimPara->accountId_);
121 HILOGI("%{public}s, %{public}s", ret ? "succ" : "fail", reclaimPara->ToString().c_str());
122 return ret;
123 }
124
NotifyAccountDied(int accountId)125 void ReclaimStrategyManager::NotifyAccountDied(int accountId)
126 {
127 if (!Initailized()) {
128 HILOGE("has not been initialized, skiped! accountId=%{public}d", accountId);
129 return;
130 }
131 if (accountId < VALID_USER_ID_MIN) {
132 HILOGE("invalid userId %{public}d, less than MIN_VALUE(%{public}d)",
133 accountId, VALID_USER_ID_MIN);
134 return;
135 }
136 std::function<bool()> func = std::bind(
137 &ReclaimStrategyManager::HandleAccountDied_, this, accountId);
138 handler_->PostImmediateTask(func);
139 }
140
NotifyAccountPriorityChanged(int accountId,int priority)141 void ReclaimStrategyManager::NotifyAccountPriorityChanged(int accountId, int priority)
142 {
143 if (!Initailized()) {
144 HILOGE("has not been initialized, skiped! accountId=%{public}d, priority=%{public}d", accountId, priority);
145 return;
146 }
147 if (accountId < VALID_USER_ID_MIN) {
148 HILOGE("invalid userId %{public}d, less than MIN_VALUE(%{public}d)",
149 accountId, VALID_USER_ID_MIN);
150 return;
151 }
152 std::function<bool()> func = std::bind(
153 &ReclaimStrategyManager::HandleAccountPriorityChanged_, this, accountId, priority);
154 handler_->PostImmediateTask(func);
155 }
156
HandleAccountDied_(int accountId)157 bool ReclaimStrategyManager::HandleAccountDied_(int accountId)
158 {
159 return MemcgMgr::GetInstance().RemoveUserMemcg(accountId);
160 }
161
HandleAccountPriorityChanged_(int accountId,int priority)162 bool ReclaimStrategyManager::HandleAccountPriorityChanged_(int accountId, int priority)
163 {
164 if (MemcgMgr::GetInstance().GetUserMemcg(accountId) == nullptr) {
165 HILOGI("account %{public}d not exist.", accountId);
166 return false;
167 }
168 GetValidScore_(priority);
169 std::unique_ptr<ReclaimRatios> ratios = nullptr;
170 try {
171 ratios = std::make_unique<ReclaimRatios>();
172 } catch (...) {
173 HILOGE("new ratios obj failed!");
174 return false;
175 }
176 if (ratios == nullptr || !GetReclaimRatiosByScore_(priority, *ratios)) {
177 HILOGE("get config ratios failed, will not update memcg ratio, userId=%{public}d", accountId);
178 ratios = nullptr;
179 return false;
180 }
181 bool ret = MemcgMgr::GetInstance().UpdateMemcgScoreAndReclaimRatios(accountId, priority, *ratios);
182 HILOGI("UpdateMemcgScoreAndReclaimRatios %{public}s, userId=%{public}d score=%{public}d %{public}s",
183 ret ? "succ" : "fail", accountId, priority, ratios->ToString().c_str());
184 ratios = nullptr;
185 return ret;
186 }
187
GetReclaimRatiosByScore_(int score,ReclaimRatios & ratios)188 bool ReclaimStrategyManager::GetReclaimRatiosByScore_(int score, ReclaimRatios& ratios)
189 {
190 HILOGD("before get ratios from MemmgrConfigManager %{public}s", ratios.NumsToString().c_str());
191 MemmgrConfigManager::ReclaimRatiosConfigSet reclaimRatiosConfigSet =
192 MemmgrConfigManager::GetInstance().GetReclaimRatiosConfigSet();
193 for (auto i = reclaimRatiosConfigSet.begin(); i != reclaimRatiosConfigSet.end(); ++i) {
194 if ((*i)->minScore <= score && (*i)->maxScore >= score) {
195 ratios.SetRatiosByValue((*i)->mem2zramRatio, (*i)->zran2ufsRation, (*i)->refaultThreshold);
196 HILOGI("get ratios from MemmgrConfigManager %{public}s", ratios.NumsToString().c_str());
197 return true;
198 }
199 }
200 HILOGD("can not get ratios from MemmgrConfigManager");
201 return false;
202 }
203
GetValidScore_(int & priority)204 void ReclaimStrategyManager::GetValidScore_(int& priority)
205 {
206 if (priority < RECLAIM_SCORE_MIN) {
207 priority = RECLAIM_SCORE_MIN;
208 } else if (priority > RECLAIM_SCORE_MAX) {
209 priority = RECLAIM_SCORE_MAX;
210 }
211 }
212 } // namespace Memory
213 } // namespace OHOS
214