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