1ba5c3796Sopenharmony_ci/*
2ba5c3796Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
3ba5c3796Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4ba5c3796Sopenharmony_ci * you may not use this->file except in compliance with the License.
5ba5c3796Sopenharmony_ci * You may obtain a copy of the License at
6ba5c3796Sopenharmony_ci *
7ba5c3796Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8ba5c3796Sopenharmony_ci *
9ba5c3796Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10ba5c3796Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11ba5c3796Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12ba5c3796Sopenharmony_ci * See the License for the specific language governing permissions and
13ba5c3796Sopenharmony_ci * limitations under the License.
14ba5c3796Sopenharmony_ci */
15ba5c3796Sopenharmony_ci
16ba5c3796Sopenharmony_ci#include <regex>
17ba5c3796Sopenharmony_ci
18ba5c3796Sopenharmony_ci#include "memmgr_log.h"
19ba5c3796Sopenharmony_ci#include "kernel_interface.h"
20ba5c3796Sopenharmony_ci#include "reclaim_strategy_constants.h"
21ba5c3796Sopenharmony_ci#include "memcg.h"
22ba5c3796Sopenharmony_ci
23ba5c3796Sopenharmony_cinamespace OHOS {
24ba5c3796Sopenharmony_cinamespace Memory {
25ba5c3796Sopenharmony_cinamespace {
26ba5c3796Sopenharmony_ciconst std::string TAG = "Memcg";
27ba5c3796Sopenharmony_ci} // namespace
28ba5c3796Sopenharmony_ci
29ba5c3796Sopenharmony_ciSwapInfo::SwapInfo()
30ba5c3796Sopenharmony_ci    : swapOutCount_(0),
31ba5c3796Sopenharmony_ci      swapOutSize_(0),
32ba5c3796Sopenharmony_ci      swapInCount_(0),
33ba5c3796Sopenharmony_ci      swapInSize_(0),
34ba5c3796Sopenharmony_ci      pageInCount_(0),
35ba5c3796Sopenharmony_ci      swapSizeCurr_(0),
36ba5c3796Sopenharmony_ci      swapSizeMax_(0) {}
37ba5c3796Sopenharmony_ci
38ba5c3796Sopenharmony_ciSwapInfo::SwapInfo(unsigned int swapOutCount, unsigned int swapOutSize, unsigned int swapInCount,
39ba5c3796Sopenharmony_ci                   unsigned int swapInSize, unsigned int pageInCount, unsigned int swapSizeCurr,
40ba5c3796Sopenharmony_ci                   unsigned int swapSizeMax)
41ba5c3796Sopenharmony_ci    : swapOutCount_(swapOutCount),
42ba5c3796Sopenharmony_ci      swapOutSize_(swapOutSize),
43ba5c3796Sopenharmony_ci      swapInCount_(swapInCount),
44ba5c3796Sopenharmony_ci      swapInSize_(swapInSize),
45ba5c3796Sopenharmony_ci      pageInCount_(pageInCount),
46ba5c3796Sopenharmony_ci      swapSizeCurr_(swapSizeCurr),
47ba5c3796Sopenharmony_ci      swapSizeMax_(swapSizeMax) {}
48ba5c3796Sopenharmony_ci
49ba5c3796Sopenharmony_ciinline std::string SwapInfo::ToString() const
50ba5c3796Sopenharmony_ci{
51ba5c3796Sopenharmony_ci    std::string ret = "swapOutCount:" + std::to_string(swapOutCount_)
52ba5c3796Sopenharmony_ci                    + " swapOutSize:" + std::to_string(swapOutSize_)
53ba5c3796Sopenharmony_ci                    + " swapInCount:" + std::to_string(swapInCount_)
54ba5c3796Sopenharmony_ci                    + " swapInSize:" + std::to_string(swapInSize_)
55ba5c3796Sopenharmony_ci                    + " pageInCount:" + std::to_string(pageInCount_)
56ba5c3796Sopenharmony_ci                    + " swapSizeCurr:" + std::to_string(swapSizeCurr_)
57ba5c3796Sopenharmony_ci                    + " swapSizeMax:" + std::to_string(swapSizeMax_);
58ba5c3796Sopenharmony_ci    return ret;
59ba5c3796Sopenharmony_ci}
60ba5c3796Sopenharmony_ci
61ba5c3796Sopenharmony_ciMemInfo::MemInfo() : anonKiB_(0), zramKiB_(0), eswapKiB_(0) {}
62ba5c3796Sopenharmony_ci
63ba5c3796Sopenharmony_ciMemInfo::MemInfo(unsigned int anonKiB, unsigned int zramKiB, unsigned int eswapKiB)
64ba5c3796Sopenharmony_ci    : anonKiB_(anonKiB),
65ba5c3796Sopenharmony_ci      zramKiB_(zramKiB),
66ba5c3796Sopenharmony_ci      eswapKiB_(eswapKiB) {}
67ba5c3796Sopenharmony_ci
68ba5c3796Sopenharmony_ciinline std::string MemInfo::ToString() const
69ba5c3796Sopenharmony_ci{
70ba5c3796Sopenharmony_ci    std::string ret = "anonKiB:" + std::to_string(anonKiB_)
71ba5c3796Sopenharmony_ci                    + " zramKiB:" + std::to_string(zramKiB_)
72ba5c3796Sopenharmony_ci                    + " eswapKiB:" + std::to_string(eswapKiB_);
73ba5c3796Sopenharmony_ci    return ret;
74ba5c3796Sopenharmony_ci}
75ba5c3796Sopenharmony_ci
76ba5c3796Sopenharmony_ciReclaimRatios::ReclaimRatios()
77ba5c3796Sopenharmony_ci    : mem2zramRatio_(MEMCG_MEM_2_ZRAM_RATIO),
78ba5c3796Sopenharmony_ci      zram2ufsRatio_(MEMCG_ZRAM_2_UFS_RATIO),
79ba5c3796Sopenharmony_ci      refaultThreshold_(MEMCG_REFAULT_THRESHOLD) {}
80ba5c3796Sopenharmony_ci
81ba5c3796Sopenharmony_ciReclaimRatios::ReclaimRatios(unsigned int mem2zramRatio, unsigned int zram2ufsRatio, unsigned int refaultThreshold)
82ba5c3796Sopenharmony_ci    : refaultThreshold_(refaultThreshold)
83ba5c3796Sopenharmony_ci{
84ba5c3796Sopenharmony_ci    mem2zramRatio_ = (mem2zramRatio > PERCENT_100) ? PERCENT_100 : mem2zramRatio;
85ba5c3796Sopenharmony_ci    zram2ufsRatio_ = (zram2ufsRatio > PERCENT_100) ? PERCENT_100 : zram2ufsRatio;
86ba5c3796Sopenharmony_ci}
87ba5c3796Sopenharmony_ci
88ba5c3796Sopenharmony_civoid ReclaimRatios::SetRatiosByValue(unsigned int mem2zramRatio, unsigned int zram2ufsRatio,
89ba5c3796Sopenharmony_ci                                     unsigned int refaultThreshold)
90ba5c3796Sopenharmony_ci{
91ba5c3796Sopenharmony_ci    mem2zramRatio_ = (mem2zramRatio > PERCENT_100) ? PERCENT_100 : mem2zramRatio;
92ba5c3796Sopenharmony_ci    zram2ufsRatio_ = (zram2ufsRatio > PERCENT_100) ? PERCENT_100 : zram2ufsRatio;
93ba5c3796Sopenharmony_ci    refaultThreshold_ = refaultThreshold;
94ba5c3796Sopenharmony_ci}
95ba5c3796Sopenharmony_ci
96ba5c3796Sopenharmony_civoid ReclaimRatios::SetRatios(const ReclaimRatios& ratios)
97ba5c3796Sopenharmony_ci{
98ba5c3796Sopenharmony_ci    SetRatiosByValue(ratios.mem2zramRatio_, ratios.zram2ufsRatio_, ratios.refaultThreshold_);
99ba5c3796Sopenharmony_ci}
100ba5c3796Sopenharmony_ci
101ba5c3796Sopenharmony_ciinline std::string ReclaimRatios::NumsToString() const
102ba5c3796Sopenharmony_ci{
103ba5c3796Sopenharmony_ci    std::string ret = std::to_string(mem2zramRatio_) + " "
104ba5c3796Sopenharmony_ci                    + std::to_string(zram2ufsRatio_) + " "
105ba5c3796Sopenharmony_ci                    + std::to_string(refaultThreshold_);
106ba5c3796Sopenharmony_ci    return ret;
107ba5c3796Sopenharmony_ci}
108ba5c3796Sopenharmony_ci
109ba5c3796Sopenharmony_cistd::string ReclaimRatios::ToString() const
110ba5c3796Sopenharmony_ci{
111ba5c3796Sopenharmony_ci    std::string ret = "mem2zramRatio:" + std::to_string(mem2zramRatio_)
112ba5c3796Sopenharmony_ci                    + " zram2ufsRatio:" + std::to_string(zram2ufsRatio_)
113ba5c3796Sopenharmony_ci                    + " refaultThreshold:" + std::to_string(refaultThreshold_);
114ba5c3796Sopenharmony_ci    return ret;
115ba5c3796Sopenharmony_ci}
116ba5c3796Sopenharmony_ci
117ba5c3796Sopenharmony_ciMemcg::Memcg() : score_(0)
118ba5c3796Sopenharmony_ci{
119ba5c3796Sopenharmony_ci    swapInfo_ = new (std::nothrow) SwapInfo();
120ba5c3796Sopenharmony_ci    memInfo_ = new (std::nothrow) MemInfo();
121ba5c3796Sopenharmony_ci    reclaimRatios_ = new (std::nothrow) ReclaimRatios();
122ba5c3796Sopenharmony_ci    if (swapInfo_ == nullptr || memInfo_ == nullptr || reclaimRatios_ == nullptr) {
123ba5c3796Sopenharmony_ci        HILOGE("new obj failed! init memcg failed");
124ba5c3796Sopenharmony_ci    } else {
125ba5c3796Sopenharmony_ci        HILOGI("init memcg success");
126ba5c3796Sopenharmony_ci    }
127ba5c3796Sopenharmony_ci}
128ba5c3796Sopenharmony_ci
129ba5c3796Sopenharmony_ciMemcg::~Memcg()
130ba5c3796Sopenharmony_ci{
131ba5c3796Sopenharmony_ci    delete swapInfo_;
132ba5c3796Sopenharmony_ci    swapInfo_ = nullptr;
133ba5c3796Sopenharmony_ci    delete memInfo_;
134ba5c3796Sopenharmony_ci    memInfo_ = nullptr;
135ba5c3796Sopenharmony_ci    delete reclaimRatios_;
136ba5c3796Sopenharmony_ci    reclaimRatios_ = nullptr;
137ba5c3796Sopenharmony_ci    HILOGI("release memcg success");
138ba5c3796Sopenharmony_ci}
139ba5c3796Sopenharmony_ci
140ba5c3796Sopenharmony_cibool Memcg::UpdateMemInfoFromKernel()
141ba5c3796Sopenharmony_ci{
142ba5c3796Sopenharmony_ci    if (memInfo_ == nullptr) {
143ba5c3796Sopenharmony_ci        HILOGE("memInfo_ nullptr");
144ba5c3796Sopenharmony_ci        return false;
145ba5c3796Sopenharmony_ci    }
146ba5c3796Sopenharmony_ci    std::string path = KernelInterface::GetInstance().JoinPath(GetMemcgPath_(), "memory.stat");
147ba5c3796Sopenharmony_ci    std::string content;
148ba5c3796Sopenharmony_ci    if (!KernelInterface::GetInstance().ReadFromFile(path, content)) {
149ba5c3796Sopenharmony_ci        HILOGE("file not found. %{public}s", path.c_str());
150ba5c3796Sopenharmony_ci        return false;
151ba5c3796Sopenharmony_ci    }
152ba5c3796Sopenharmony_ci    content = std::regex_replace(content, std::regex("\n+"), " "); // replace \n with space
153ba5c3796Sopenharmony_ci    std::regex re(".*Anon:[[:s:]]*([[:d:]]+) kB[[:s:]]*"
154ba5c3796Sopenharmony_ci                  ".*[zZ]ram:[[:s:]]*([[:d:]]+) kB[[:s:]]*"
155ba5c3796Sopenharmony_ci                  "Eswap:[[:s:]]*([[:d:]]+) kB[[:s:]]*");
156ba5c3796Sopenharmony_ci    std::smatch res;
157ba5c3796Sopenharmony_ci    if (!std::regex_match(content, res, re)) {
158ba5c3796Sopenharmony_ci        HILOGI("re not match. %{public}s", content.c_str());
159ba5c3796Sopenharmony_ci        return false;
160ba5c3796Sopenharmony_ci    }
161ba5c3796Sopenharmony_ci    try {
162ba5c3796Sopenharmony_ci        memInfo_->anonKiB_ = (unsigned int)std::stoi(res.str(1)); // 1: anonKiB index
163ba5c3796Sopenharmony_ci        memInfo_->zramKiB_ = (unsigned int)std::stoi(res.str(2)); // 2: zramKiB index
164ba5c3796Sopenharmony_ci        memInfo_->eswapKiB_ = (unsigned int)std::stoi(res.str(3)); // 3: eswapKiB index
165ba5c3796Sopenharmony_ci    } catch (std::out_of_range&) {
166ba5c3796Sopenharmony_ci        HILOGE("stoi() failed: out_of_range");
167ba5c3796Sopenharmony_ci        return false;
168ba5c3796Sopenharmony_ci    }
169ba5c3796Sopenharmony_ci    HILOGI("success. %{public}s", memInfo_->ToString().c_str());
170ba5c3796Sopenharmony_ci    return true;
171ba5c3796Sopenharmony_ci}
172ba5c3796Sopenharmony_ci
173ba5c3796Sopenharmony_civoid Memcg::SetScore(int score)
174ba5c3796Sopenharmony_ci{
175ba5c3796Sopenharmony_ci    score_ = score;
176ba5c3796Sopenharmony_ci}
177ba5c3796Sopenharmony_ci
178ba5c3796Sopenharmony_civoid Memcg::SetReclaimRatios(unsigned int mem2zramRatio, unsigned int zram2ufsRatio, unsigned int refaultThreshold)
179ba5c3796Sopenharmony_ci{
180ba5c3796Sopenharmony_ci    if (reclaimRatios_ == nullptr) {
181ba5c3796Sopenharmony_ci        HILOGE("reclaimRatios_ nullptr");
182ba5c3796Sopenharmony_ci        return;
183ba5c3796Sopenharmony_ci    }
184ba5c3796Sopenharmony_ci    reclaimRatios_->mem2zramRatio_ = (mem2zramRatio > PERCENT_100) ? PERCENT_100 : mem2zramRatio;
185ba5c3796Sopenharmony_ci    reclaimRatios_->zram2ufsRatio_ = (zram2ufsRatio > PERCENT_100) ? PERCENT_100 : zram2ufsRatio;
186ba5c3796Sopenharmony_ci    reclaimRatios_->refaultThreshold_ = refaultThreshold;
187ba5c3796Sopenharmony_ci}
188ba5c3796Sopenharmony_ci
189ba5c3796Sopenharmony_cibool Memcg::SetReclaimRatios(const ReclaimRatios& ratios)
190ba5c3796Sopenharmony_ci{
191ba5c3796Sopenharmony_ci    if (reclaimRatios_ == nullptr) {
192ba5c3796Sopenharmony_ci        HILOGE("reclaimRatios_ nullptr");
193ba5c3796Sopenharmony_ci        return false;
194ba5c3796Sopenharmony_ci    }
195ba5c3796Sopenharmony_ci    reclaimRatios_->SetRatios(ratios);
196ba5c3796Sopenharmony_ci    return true;
197ba5c3796Sopenharmony_ci}
198ba5c3796Sopenharmony_ci
199ba5c3796Sopenharmony_cibool Memcg::SetScoreAndReclaimRatiosToKernel()
200ba5c3796Sopenharmony_ci{
201ba5c3796Sopenharmony_ci    if (reclaimRatios_ == nullptr) {
202ba5c3796Sopenharmony_ci        HILOGE("reclaimRatios_ nullptr");
203ba5c3796Sopenharmony_ci        return false;
204ba5c3796Sopenharmony_ci    }
205ba5c3796Sopenharmony_ci    bool ret = false;
206ba5c3796Sopenharmony_ci    // write score
207ba5c3796Sopenharmony_ci    std::string scorePath = KernelInterface::GetInstance().JoinPath(GetMemcgPath_(), "memory.app_score");
208ba5c3796Sopenharmony_ci    ret = WriteToFile_(scorePath, std::to_string(score_));
209ba5c3796Sopenharmony_ci    // write reclaim ratios
210ba5c3796Sopenharmony_ci    std::string ratiosPath = KernelInterface::GetInstance().JoinPath(GetMemcgPath_(),
211ba5c3796Sopenharmony_ci        "memory.zswapd_single_memcg_param");
212ba5c3796Sopenharmony_ci    ret = ret && WriteToFile_(ratiosPath, reclaimRatios_->NumsToString());
213ba5c3796Sopenharmony_ci    // double check: check file content
214ba5c3796Sopenharmony_ci    int score = 0;
215ba5c3796Sopenharmony_ci    unsigned int mem2zramRatio = 0;
216ba5c3796Sopenharmony_ci    unsigned int zram2ufsRatio = 0;
217ba5c3796Sopenharmony_ci    unsigned int refaultThreshold = 0;
218ba5c3796Sopenharmony_ci    if (!ReadScoreAndReclaimRatiosFromKernel_(score, mem2zramRatio, zram2ufsRatio, refaultThreshold)) {
219ba5c3796Sopenharmony_ci        return ret;
220ba5c3796Sopenharmony_ci    }
221ba5c3796Sopenharmony_ci    ret = ret && (score_ == score);
222ba5c3796Sopenharmony_ci    ret = ret && (reclaimRatios_->mem2zramRatio_ == mem2zramRatio);
223ba5c3796Sopenharmony_ci    ret = ret && (reclaimRatios_->zram2ufsRatio_ == zram2ufsRatio);
224ba5c3796Sopenharmony_ci    ret = ret && (reclaimRatios_->refaultThreshold_ == refaultThreshold);
225ba5c3796Sopenharmony_ci    if (ret == false) { // if values of mem and kernel not matched, using kernel values
226ba5c3796Sopenharmony_ci        score_ = score;
227ba5c3796Sopenharmony_ci        reclaimRatios_->mem2zramRatio_ = mem2zramRatio;
228ba5c3796Sopenharmony_ci        reclaimRatios_->zram2ufsRatio_ = zram2ufsRatio;
229ba5c3796Sopenharmony_ci        reclaimRatios_->refaultThreshold_ = refaultThreshold;
230ba5c3796Sopenharmony_ci    }
231ba5c3796Sopenharmony_ci    return ret;
232ba5c3796Sopenharmony_ci}
233ba5c3796Sopenharmony_ci
234ba5c3796Sopenharmony_cibool Memcg::SwapIn()
235ba5c3796Sopenharmony_ci{
236ba5c3796Sopenharmony_ci    std::string zramPath = KernelInterface::GetInstance().JoinPath(GetMemcgPath_(), "memory.ub_ufs2zram_ratio");
237ba5c3796Sopenharmony_ci    bool ret = WriteToFile_(zramPath, std::to_string(PERCENT_100)); // load 100% to zram
238ba5c3796Sopenharmony_ci    std::string swapinPath = KernelInterface::GetInstance().JoinPath(GetMemcgPath_(), "memory.force_swapin");
239ba5c3796Sopenharmony_ci    ret = ret && WriteToFile_(swapinPath, "0"); // echo 0 to trigger force swapin
240ba5c3796Sopenharmony_ci    return ret;
241ba5c3796Sopenharmony_ci}
242ba5c3796Sopenharmony_ci
243ba5c3796Sopenharmony_ciinline std::string Memcg::GetMemcgPath_()
244ba5c3796Sopenharmony_ci{
245ba5c3796Sopenharmony_ci    // memcg dir: "/dev/memcg"
246ba5c3796Sopenharmony_ci    return KernelInterface::MEMCG_BASE_PATH;
247ba5c3796Sopenharmony_ci}
248ba5c3796Sopenharmony_ci
249ba5c3796Sopenharmony_ciinline bool Memcg::WriteToFile_(const std::string& path, const std::string& content, bool truncated)
250ba5c3796Sopenharmony_ci{
251ba5c3796Sopenharmony_ci    std::string op = truncated ? ">" : ">>";
252ba5c3796Sopenharmony_ci    if (!KernelInterface::GetInstance().WriteToFile(path, content, truncated)) {
253ba5c3796Sopenharmony_ci        HILOGE("failed. %{public}s %{public}s %{public}s", content.c_str(), op.c_str(), path.c_str());
254ba5c3796Sopenharmony_ci        return false;
255ba5c3796Sopenharmony_ci    }
256ba5c3796Sopenharmony_ci    HILOGI("success. %{public}s %{public}s %{public}s", content.c_str(), op.c_str(), path.c_str());
257ba5c3796Sopenharmony_ci    return true;
258ba5c3796Sopenharmony_ci}
259ba5c3796Sopenharmony_ci
260ba5c3796Sopenharmony_cibool Memcg::ReadScoreAndReclaimRatiosFromKernel_(int& score, unsigned int& mem2zramRatio,
261ba5c3796Sopenharmony_ci    unsigned int& zram2ufsRatio, unsigned int& refaultThreshold)
262ba5c3796Sopenharmony_ci{
263ba5c3796Sopenharmony_ci    std::string path = KernelInterface::GetInstance().JoinPath(GetMemcgPath_(), "memory.zswapd_single_memcg_param");
264ba5c3796Sopenharmony_ci    std::string content;
265ba5c3796Sopenharmony_ci    if (!KernelInterface::GetInstance().ReadFromFile(path, content)) {
266ba5c3796Sopenharmony_ci        HILOGE("file not found. %{public}s", path.c_str());
267ba5c3796Sopenharmony_ci        return false;
268ba5c3796Sopenharmony_ci    }
269ba5c3796Sopenharmony_ci    content = std::regex_replace(content, std::regex("\n+"), " "); // replace \n with space
270ba5c3796Sopenharmony_ci    std::regex re("memcg score:[[:s:]]*([[:d:]]+)[[:s:]]*"
271ba5c3796Sopenharmony_ci                  "memcg ub_mem2zram_ratio:[[:s:]]*([[:d:]]+)[[:s:]]*"
272ba5c3796Sopenharmony_ci                  "memcg ub_zram2ufs_ratio:[[:s:]]*([[:d:]]+)[[:s:]]*"
273ba5c3796Sopenharmony_ci                  "memcg refault_threshold:[[:s:]]*([[:d:]]+)[[:s:]]*");
274ba5c3796Sopenharmony_ci    std::smatch res;
275ba5c3796Sopenharmony_ci    if (!std::regex_match(content, res, re)) {
276ba5c3796Sopenharmony_ci        HILOGI("re not match. %{public}s", content.c_str());
277ba5c3796Sopenharmony_ci        return false;
278ba5c3796Sopenharmony_ci    }
279ba5c3796Sopenharmony_ci    try {
280ba5c3796Sopenharmony_ci        score = std::stoi(res.str(1)); // 1: memcg score index
281ba5c3796Sopenharmony_ci        mem2zramRatio = (unsigned int)std::stoi(res.str(2)); // 2: memcg mem2zramRatio index
282ba5c3796Sopenharmony_ci        zram2ufsRatio = (unsigned int)std::stoi(res.str(3)); // 3: memcg zram2ufsRatio index
283ba5c3796Sopenharmony_ci        refaultThreshold = (unsigned int)std::stoi(res.str(4)); // 4: memcg refaultThreshold index
284ba5c3796Sopenharmony_ci    } catch (std::out_of_range&) {
285ba5c3796Sopenharmony_ci        HILOGE("stoi() failed: out_of_range");
286ba5c3796Sopenharmony_ci        return false;
287ba5c3796Sopenharmony_ci    }
288ba5c3796Sopenharmony_ci    return true;
289ba5c3796Sopenharmony_ci}
290ba5c3796Sopenharmony_ci
291ba5c3796Sopenharmony_ciUserMemcg::UserMemcg(unsigned int userId) : userId_(userId)
292ba5c3796Sopenharmony_ci{
293ba5c3796Sopenharmony_ci    HILOGI("init UserMemcg success");
294ba5c3796Sopenharmony_ci}
295ba5c3796Sopenharmony_ci
296ba5c3796Sopenharmony_ciUserMemcg::~UserMemcg()
297ba5c3796Sopenharmony_ci{
298ba5c3796Sopenharmony_ci    HILOGI("release UserMemcg success");
299ba5c3796Sopenharmony_ci}
300ba5c3796Sopenharmony_ci
301ba5c3796Sopenharmony_cibool UserMemcg::CreateMemcgDir()
302ba5c3796Sopenharmony_ci{
303ba5c3796Sopenharmony_ci    std::string fullPath = GetMemcgPath_();
304ba5c3796Sopenharmony_ci    if (!KernelInterface::GetInstance().CreateDir(fullPath)) {
305ba5c3796Sopenharmony_ci        HILOGE("failed. %{public}s", fullPath.c_str());
306ba5c3796Sopenharmony_ci        return false;
307ba5c3796Sopenharmony_ci    }
308ba5c3796Sopenharmony_ci    HILOGI("success. %{public}s", fullPath.c_str());
309ba5c3796Sopenharmony_ci    return true;
310ba5c3796Sopenharmony_ci}
311ba5c3796Sopenharmony_ci
312ba5c3796Sopenharmony_cibool UserMemcg::RemoveMemcgDir()
313ba5c3796Sopenharmony_ci{
314ba5c3796Sopenharmony_ci    std::string fullPath = GetMemcgPath_();
315ba5c3796Sopenharmony_ci    if (!KernelInterface::GetInstance().RemoveDirRecursively(fullPath)) {
316ba5c3796Sopenharmony_ci        HILOGE("failed. %{public}s", fullPath.c_str());
317ba5c3796Sopenharmony_ci        return false;
318ba5c3796Sopenharmony_ci    }
319ba5c3796Sopenharmony_ci    HILOGI("success. %{public}s", fullPath.c_str());
320ba5c3796Sopenharmony_ci    return true;
321ba5c3796Sopenharmony_ci}
322ba5c3796Sopenharmony_ci
323ba5c3796Sopenharmony_cistd::string UserMemcg::GetMemcgPath_()
324ba5c3796Sopenharmony_ci{
325ba5c3796Sopenharmony_ci    // user memcg dir: "/dev/memcg/${userId}"
326ba5c3796Sopenharmony_ci    return KernelInterface::GetInstance().JoinPath(KernelInterface::MEMCG_BASE_PATH, std::to_string(userId_));
327ba5c3796Sopenharmony_ci}
328ba5c3796Sopenharmony_ci
329ba5c3796Sopenharmony_cibool UserMemcg::AddProc(unsigned int pid)
330ba5c3796Sopenharmony_ci{
331ba5c3796Sopenharmony_ci    std::string fullPath = KernelInterface::GetInstance().JoinPath(GetMemcgPath_(), "cgroup.procs");
332ba5c3796Sopenharmony_ci    bool ret = WriteToFile_(fullPath, std::to_string(pid), false);
333ba5c3796Sopenharmony_ci    // double check file content
334ba5c3796Sopenharmony_ci    bool dirExists = KernelInterface::GetInstance().IsDirExists(GetMemcgPath_());
335ba5c3796Sopenharmony_ci    bool fileExists = KernelInterface::GetInstance().IsFileExists(fullPath);
336ba5c3796Sopenharmony_ci    std::string content;
337ba5c3796Sopenharmony_ci    KernelInterface::GetInstance().ReadFromFile(fullPath, content);
338ba5c3796Sopenharmony_ci    content = std::regex_replace(content, std::regex("\n+"), " "); // replace \n with space
339ba5c3796Sopenharmony_ci    HILOGI("dir:%{public}s exist=%{public}d. file:%{public}s exist=%{public}d content=*%{public}s* ret=%{public}d",
340ba5c3796Sopenharmony_ci           GetMemcgPath_().c_str(), dirExists, fullPath.c_str(), fileExists, content.c_str(), ret);
341ba5c3796Sopenharmony_ci    return ret;
342ba5c3796Sopenharmony_ci}
343ba5c3796Sopenharmony_ci} // namespace Memory
344ba5c3796Sopenharmony_ci} // namespace OHOS
345