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