1 /*
2 * Copyright (C) 2021-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 "executor/memory/memory_info.h"
16 
17 #include <dlfcn.h>
18 #include <cinttypes>
19 #include <fstream>
20 #include <numeric>
21 #include <thread>
22 #include <v1_0/imemory_tracker_interface.h>
23 
24 #include "dump_common_utils.h"
25 #include "dump_utils.h"
26 #include "executor/memory/get_cma_info.h"
27 #include "executor/memory/get_heap_info.h"
28 #include "executor/memory/get_hardware_info.h"
29 #include "executor/memory/get_kernel_info.h"
30 #include "executor/memory/get_process_info.h"
31 #include "executor/memory/get_ram_info.h"
32 #include "executor/memory/memory_util.h"
33 #include "executor/memory/parse/meminfo_data.h"
34 #include "executor/memory/parse/parse_meminfo.h"
35 #include "executor/memory/parse/parse_smaps_rollup_info.h"
36 #include "executor/memory/parse/parse_smaps_info.h"
37 #include "file_ex.h"
38 #include "hdf_base.h"
39 #include "hilog_wrapper.h"
40 #include "securec.h"
41 #include "string_ex.h"
42 #include "util/string_utils.h"
43 #include "util/file_utils.h"
44 
45 using namespace std;
46 using namespace OHOS::HDI::Memorytracker::V1_0;
47 
48 namespace OHOS {
49 namespace HiviewDFX {
50 static const std::string LIB = "libai_mnt_client.so";
51 
52 static const std::string UNKNOWN_PROCESS = "unknown";
53 static const std::string PRE_BLANK = "   ";
54 static const std::string MEMORY_LINE = "-------------------------------[memory]-------------------------------";
55 constexpr char HIAI_MEM_INFO_FN[] = "HIAI_Memory_QueryAllUserAllocatedMemInfo";
56 constexpr int PAGETAG_MIN_LEN = 2;
57 using HiaiFunc = int (*)(MemInfoData::HiaiUserAllocatedMemInfo*, int, int*);
58 
MemoryInfo()59 MemoryInfo::MemoryInfo()
60 {
61     methodVec_.clear();
62     methodVec_.push_back(make_pair(MEMINFO_PSS,
63         bind(&MemoryInfo::SetPss, this, placeholders::_1, placeholders::_2)));
64     methodVec_.push_back(make_pair(MEMINFO_SHARED_CLEAN,
65         bind(&MemoryInfo::SetSharedClean, this, placeholders::_1, placeholders::_2)));
66     methodVec_.push_back(make_pair(MEMINFO_SHARED_DIRTY,
67         bind(&MemoryInfo::SetSharedDirty, this, placeholders::_1, placeholders::_2)));
68     methodVec_.push_back(make_pair(MEMINFO_PRIVATE_CLEAN,
69         bind(&MemoryInfo::SetPrivateClean, this, placeholders::_1, placeholders::_2)));
70     methodVec_.push_back(make_pair(MEMINFO_PRIVATE_DIRTY,
71         bind(&MemoryInfo::SetPrivateDirty, this, placeholders::_1, placeholders::_2)));
72     methodVec_.push_back(make_pair(MEMINFO_SWAP,
73         bind(&MemoryInfo::SetSwap, this, placeholders::_1, placeholders::_2)));
74     methodVec_.push_back(make_pair(MEMINFO_SWAP_PSS,
75         bind(&MemoryInfo::SetSwapPss, this, placeholders::_1, placeholders::_2)));
76     methodVec_.push_back(make_pair(MEMINFO_HEAP_SIZE,
77         bind(&MemoryInfo::SetHeapSize, this, placeholders::_1, placeholders::_2)));
78     methodVec_.push_back(make_pair(MEMINFO_HEAP_ALLOC,
79         bind(&MemoryInfo::SetHeapAlloc, this, placeholders::_1, placeholders::_2)));
80     methodVec_.push_back(make_pair(MEMINFO_HEAP_FREE,
81         bind(&MemoryInfo::SetHeapFree, this, placeholders::_1, placeholders::_2)));
82 }
83 
~MemoryInfo()84 MemoryInfo::~MemoryInfo()
85 {
86 }
87 
insertMemoryTitle(StringMatrix result)88 void MemoryInfo::insertMemoryTitle(StringMatrix result)
89 {
90     // Pss        Shared   ---- this line is line1
91     // Total      Clean    ---- this line is line2
92     // (KB)         (KB)    ---- this line is line3
93     // -----      ------   ---- this line is line4
94 
95     vector<string> line1;
96     vector<string> line2;
97     vector<string> line3;
98     vector<string> line4;
99 
100     string space = " ";
101     StringUtils::GetInstance().SetWidth(LINE_WIDTH_, BLANK_, false, space);
102 
103     string separator = "-";
104     StringUtils::GetInstance().SetWidth(LINE_WIDTH_, SEPARATOR_, false, separator);
105 
106     string unit = "(" + MemoryUtil::GetInstance().KB_UNIT_ + " )";
107     StringUtils::GetInstance().SetWidth(LINE_WIDTH_, BLANK_, false, unit);
108 
109     // Add  spaces at the beginning of the line
110     line1.push_back(space + BLANK_);
111     line2.push_back(space + BLANK_);
112     line3.push_back(space + BLANK_);
113     line4.push_back(space);
114 
115     for (string str : MemoryFilter::GetInstance().TITLE_HAS_PID_) {
116         vector<string> types;
117         StringUtils::GetInstance().StringSplit(str, "_", types);
118         if (types.size() == TYPE_SIZE) {
119             string title1 = types.at(0);
120             StringUtils::GetInstance().SetWidth(LINE_WIDTH_, BLANK_, false, title1);
121             line1.push_back(title1 + BLANK_);
122 
123             string title2 = types.at(1);
124             StringUtils::GetInstance().SetWidth(LINE_WIDTH_, BLANK_, false, title2);
125             line2.push_back(title2 + BLANK_);
126             line3.push_back(unit + BLANK_);
127             line4.push_back(separator + SEPARATOR_);
128         }
129     }
130     result->push_back(line1);
131     result->push_back(line2);
132     result->push_back(line3);
133     result->push_back(line4);
134 }
135 
BuildResult(const GroupMap & infos,StringMatrix result)136 void MemoryInfo::BuildResult(const GroupMap &infos, StringMatrix result)
137 {
138     insertMemoryTitle(result);
139     for (const auto &info : infos) {
140         vector<string> tempResult;
141         vector<string> pageTag;
142         StringUtils::GetInstance().StringSplit(info.first, "#", pageTag);
143         string group;
144         if (pageTag.size() < PAGETAG_MIN_LEN) {
145             DUMPER_HILOGE(MODULE_COMMON, "Infos are invalid, info.first: %s", info.first.c_str());
146             return;
147         }
148         if (pageTag[1] == "other") {
149             group = pageTag[0] == MemoryFilter::GetInstance().FILE_PAGE_TAG ? "FilePage other" : "AnonPage other";
150         } else {
151             group = pageTag[1];
152         }
153         StringUtils::GetInstance().SetWidth(LINE_WIDTH_, BLANK_, false, group);
154         tempResult.push_back(group + BLANK_);
155 
156         auto &valueMap = info.second;
157         for (const auto &tag : MemoryFilter::GetInstance().VALUE_WITH_PID) {
158             auto it = valueMap.find(tag);
159             string value = "0";
160             if (it != valueMap.end()) {
161                 value = to_string(it->second);
162             }
163             StringUtils::GetInstance().SetWidth(LINE_WIDTH_, BLANK_, false, value);
164             tempResult.push_back(value + BLANK_);
165         }
166         result->push_back(tempResult);
167     }
168 }
169 
170 
CalcGroup(const GroupMap & infos,StringMatrix result)171 void MemoryInfo::CalcGroup(const GroupMap &infos, StringMatrix result)
172 {
173     MemInfoData::MemInfo meminfo;
174     MemoryUtil::GetInstance().InitMemInfo(meminfo);
175     for (const auto &info : infos) {
176         auto &valueMap = info.second;
177         for (const auto &method : methodVec_) {
178             auto it = valueMap.find(method.first);
179             if (it != valueMap.end()) {
180                 method.second(meminfo, it->second);
181             }
182         }
183     }
184 
185     vector<string> lines;
186     vector<string> values;
187 
188     MemoryUtil::GetInstance().SetMemTotalValue("Total", lines, values);
189     MemoryUtil::GetInstance().SetMemTotalValue(to_string(meminfo.pss + meminfo.swapPss), lines, values);
190     MemoryUtil::GetInstance().SetMemTotalValue(to_string(meminfo.sharedClean), lines, values);
191     MemoryUtil::GetInstance().SetMemTotalValue(to_string(meminfo.sharedDirty), lines, values);
192     MemoryUtil::GetInstance().SetMemTotalValue(to_string(meminfo.privateClean), lines, values);
193     MemoryUtil::GetInstance().SetMemTotalValue(to_string(meminfo.privateDirty), lines, values);
194     MemoryUtil::GetInstance().SetMemTotalValue(to_string(meminfo.swap), lines, values);
195     MemoryUtil::GetInstance().SetMemTotalValue(to_string(meminfo.swapPss), lines, values);
196     MemoryUtil::GetInstance().SetMemTotalValue(to_string(meminfo.heapSize), lines, values);
197     MemoryUtil::GetInstance().SetMemTotalValue(to_string(meminfo.heapAlloc), lines, values);
198     MemoryUtil::GetInstance().SetMemTotalValue(to_string(meminfo.heapFree), lines, values);
199     // delete the last separator
200     if (!lines.empty()) {
201         lines.pop_back();
202         string separator = "-";
203         StringUtils::GetInstance().SetWidth(LINE_WIDTH_, SEPARATOR_, false, separator);
204         lines.push_back(separator);
205     }
206     result->push_back(lines);
207     result->push_back(values);
208 }
209 
210 
GetMemoryInfoByPid(const int32_t & pid,StringMatrix result)211 bool MemoryInfo::GetMemoryInfoByPid(const int32_t &pid, StringMatrix result)
212 {
213     std::lock_guard<std::mutex> lock(mutex_);
214     GroupMap groupMap;
215     GroupMap nativeGroupMap;
216     unique_ptr<ParseSmapsInfo> parseSmapsInfo = make_unique<ParseSmapsInfo>();
217     if (!parseSmapsInfo->GetInfo(MemoryFilter::APPOINT_PID, pid, nativeGroupMap, groupMap)) {
218         DUMPER_HILOGE(MODULE_SERVICE, "parse smaps info fail, pid:%{public}d", pid);
219         return false;
220     }
221 
222     unique_ptr<GetHeapInfo> getHeapInfo = make_unique<GetHeapInfo>();
223     if (!getHeapInfo->GetInfo(MemoryFilter::APPOINT_PID, pid, groupMap)) {
224         DUMPER_HILOGE(MODULE_SERVICE, "get heap info fail");
225         return false;
226     }
227 
228     MemInfoData::GraphicsMemory graphicsMemory;
229     MemoryUtil::GetInstance().InitGraphicsMemory(graphicsMemory);
230     GetGraphicsMemory(pid, graphicsMemory, GraphicType::GL);
231     GetGraphicsMemory(pid, graphicsMemory, GraphicType::GRAPH);
232     SetGraphGroupMap(groupMap, graphicsMemory);
233     BuildResult(groupMap, result);
234     CalcGroup(groupMap, result);
235     GetNativeHeap(nativeGroupMap, result);
236     GetPurgByPid(pid, result);
237     GetDmaByPid(graphicsMemory, result);
238     GetHiaiServerIon(pid, result);
239     return true;
240 }
241 
SetGraphGroupMap(GroupMap & groupMap,MemInfoData::GraphicsMemory & graphicsMemory)242 void MemoryInfo::SetGraphGroupMap(GroupMap& groupMap, MemInfoData::GraphicsMemory &graphicsMemory)
243 {
244     map<string, uint64_t> valueMap;
245     valueMap.insert(pair<string, uint64_t>("Pss", graphicsMemory.gl));
246     valueMap.insert(pair<string, uint64_t>("Private_Dirty", graphicsMemory.gl));
247     groupMap.insert(pair<string, map<string, uint64_t>>("AnonPage # GL", valueMap));
248     valueMap.clear();
249     valueMap.insert(pair<string, uint64_t>("Pss", graphicsMemory.graph));
250     valueMap.insert(pair<string, uint64_t>("Private_Dirty", graphicsMemory.graph));
251     groupMap.insert(pair<string, map<string, uint64_t>>("AnonPage # Graph", valueMap));
252 }
253 
AddKbUnit(const uint64_t & value) const254 string MemoryInfo::AddKbUnit(const uint64_t &value) const
255 {
256     return to_string(value) + MemoryUtil::GetInstance().KB_UNIT_;
257 }
258 
GetSmapsInfoNoPid(const int32_t & pid,GroupMap & result)259 bool MemoryInfo::GetSmapsInfoNoPid(const int32_t &pid, GroupMap &result)
260 {
261     GroupMap NativeMap;
262     unique_ptr<ParseSmapsInfo> parseSmapsInfo = make_unique<ParseSmapsInfo>();
263     return parseSmapsInfo->GetInfo(MemoryFilter::NOT_SPECIFIED_PID, pid, NativeMap, result);
264 }
265 
GetMeminfo(ValueMap & result)266 bool MemoryInfo::GetMeminfo(ValueMap &result)
267 {
268     unique_ptr<ParseMeminfo> parseMeminfo = make_unique<ParseMeminfo>();
269     return parseMeminfo->GetMeminfo(result);
270 }
271 
GetHardWareUsage(StringMatrix result)272 bool MemoryInfo::GetHardWareUsage(StringMatrix result)
273 {
274     uint64_t value;
275     unique_ptr<GetHardwareInfo> getHardwareInfo = make_unique<GetHardwareInfo>();
276     if (getHardwareInfo->GetHardwareUsage(value)) {
277         string title = "Hardware Usage:";
278         StringUtils::GetInstance().SetWidth(RAM_WIDTH_, BLANK_, false, title);
279         SaveStringToFd(rawParamFd_, title + AddKbUnit(value) + "\n");
280         return true;
281     }
282     return false;
283 }
284 
GetCMAUsage(StringMatrix result)285 bool MemoryInfo::GetCMAUsage(StringMatrix result)
286 {
287     uint64_t value = 0;
288     unique_ptr<GetCMAInfo> getCMAInfo = make_unique<GetCMAInfo>();
289     bool success = getCMAInfo->GetUsed(value);
290     if (success) {
291         string title = "CMA Usage:";
292         StringUtils::GetInstance().SetWidth(RAM_WIDTH_, BLANK_, false, title);
293         SaveStringToFd(rawParamFd_, title + AddKbUnit(value) + "\n");
294     }
295     return success;
296 }
297 
GetKernelUsage(const ValueMap & infos,StringMatrix result)298 bool MemoryInfo::GetKernelUsage(const ValueMap &infos, StringMatrix result)
299 {
300     uint64_t value = 0;
301     unique_ptr<GetKernelInfo> getGetKernelInfo = make_unique<GetKernelInfo>();
302     bool success = getGetKernelInfo->GetKernel(infos, value);
303     if (success) {
304         string title = "Kernel Usage:";
305         StringUtils::GetInstance().SetWidth(RAM_WIDTH_, BLANK_, false, title);
306         SaveStringToFd(rawParamFd_, title + AddKbUnit(value) + "\n");
307     }
308     return success;
309 }
310 
GetProcesses(const GroupMap & infos,StringMatrix result)311 void MemoryInfo::GetProcesses(const GroupMap &infos, StringMatrix result)
312 {
313     uint64_t value = 0;
314 
315     unique_ptr<GetProcessInfo> getProcessInfo = make_unique<GetProcessInfo>();
316     value = getProcessInfo->GetProcess(infos);
317 
318     string title = "Processes Usage:";
319     StringUtils::GetInstance().SetWidth(RAM_WIDTH_, BLANK_, false, title);
320     SaveStringToFd(rawParamFd_, title + AddKbUnit(value) + "\n");
321 }
322 
GetPssTotal(const GroupMap & infos,StringMatrix result)323 void MemoryInfo::GetPssTotal(const GroupMap &infos, StringMatrix result)
324 {
325     SaveStringToFd(rawParamFd_, "Total Pss by Category:\n");
326     vector<pair<string, uint64_t>> filePage;
327     vector<pair<string, uint64_t>> anonPage;
328     for (const auto &info : infos) {
329         vector<string> pageTag;
330         StringUtils::GetInstance().StringSplit(info.first, "#", pageTag);
331         if (pageTag.size() < PAGETAG_MIN_LEN) {
332             DUMPER_HILOGE(MODULE_COMMON, "Infos are invalid, info.first: %{public}s", info.first.c_str());
333             continue;
334         }
335         string group = pageTag[1];
336         auto &valueMap = info.second;
337         uint64_t pssValue = 0;
338         for (const auto &str : MemoryFilter::GetInstance().CALC_PSS_TOTAL_) {
339             auto it = valueMap.find(str);
340             if (it != valueMap.end()) {
341                 pssValue += it->second;
342             }
343         }
344 
345         if (pageTag[0] == MemoryFilter::GetInstance().FILE_PAGE_TAG) {
346             filePage.push_back(make_pair(group, pssValue));
347         } else {
348             anonPage.push_back(make_pair(group, pssValue));
349         }
350     }
351     PairToStringMatrix(MemoryFilter::GetInstance().FILE_PAGE_TAG, filePage, result);
352     PairToStringMatrix(MemoryFilter::GetInstance().ANON_PAGE_TAG, anonPage, result);
353 
354     vector<pair<string, uint64_t>> gpuValue;
355     gpuValue.push_back(make_pair(MemoryFilter::GetInstance().GL_OUT_LABEL, totalGL_));
356     PairToStringMatrix(MemoryFilter::GetInstance().GPU_TAG, gpuValue, result);
357 
358     vector<pair<string, uint64_t>> graphValue;
359     graphValue.push_back(make_pair(MemoryFilter::GetInstance().GRAPH_OUT_LABEL, totalGraph_));
360     PairToStringMatrix(MemoryFilter::GetInstance().GRAPH_OUT_LABEL, graphValue, result);
361 
362     vector<pair<string, uint64_t>> dmaValue;
363     dmaValue.push_back(make_pair(MemoryFilter::GetInstance().DMA_OUT_LABEL, totalDma_));
364     PairToStringMatrix(MemoryFilter::GetInstance().DMA_TAG, dmaValue, result);
365 }
366 
PairToStringMatrix(const string & titleStr,vector<pair<string,uint64_t>> & vec,StringMatrix result)367 void MemoryInfo::PairToStringMatrix(const string &titleStr, vector<pair<string, uint64_t>> &vec, StringMatrix result)
368 {
369     uint64_t totalPss = accumulate(vec.begin(), vec.end(), (uint64_t)0, [] (uint64_t a, pair<string, uint64_t> &b) {
370         return a + b.second;
371     });
372     SaveStringToFd(rawParamFd_, titleStr + "(" + AddKbUnit(totalPss) + "):\n");
373 
374     std::sort(vec.begin(), vec.end(),
375         [] (pair<string, uint64_t> &left, pair<string, uint64_t> &right) {
376         return right.second < left.second;
377     });
378     for (const auto &pair : vec) {
379         string pssStr = AddKbUnit(pair.second);
380         StringUtils::GetInstance().SetWidth(RAM_WIDTH_, BLANK_, false, pssStr);
381         SaveStringToFd(rawParamFd_, pssStr + " : " + pair.first + "\n");
382     }
383 }
384 
GetRamUsage(const GroupMap & smapsinfos,const ValueMap & meminfo,StringMatrix result)385 void MemoryInfo::GetRamUsage(const GroupMap &smapsinfos, const ValueMap &meminfo, StringMatrix result)
386 {
387     unique_ptr<GetRamInfo> getRamInfo = make_unique<GetRamInfo>();
388     GetRamInfo::Ram ram = getRamInfo->GetRam(smapsinfos, meminfo);
389 
390     string totalTitle = "Total RAM:";
391     StringUtils::GetInstance().SetWidth(RAM_WIDTH_, BLANK_, false, totalTitle);
392     SaveStringToFd(rawParamFd_, totalTitle + AddKbUnit(ram.total) + "\n");
393 
394     string freeTitle = "Free RAM:";
395     StringUtils::GetInstance().SetWidth(RAM_WIDTH_, BLANK_, false, freeTitle);
396     SaveStringToFd(rawParamFd_, freeTitle + AddKbUnit(ram.free) +
397         " (" + to_string(ram.cachedInfo) + " cached + " + to_string(ram.freeInfo) + " free)\n");
398 
399     string usedTitle = "Used RAM:";
400     StringUtils::GetInstance().SetWidth(RAM_WIDTH_, BLANK_, false, usedTitle);
401     SaveStringToFd(rawParamFd_, usedTitle + AddKbUnit(ram.used) +
402         " (" + to_string(ram.totalPss) + " total pss + " + to_string(ram.kernelUsed) + " kernel)\n");
403 
404     string lostTitle = "Lost RAM:";
405     StringUtils::GetInstance().SetWidth(RAM_WIDTH_, BLANK_, false, lostTitle);
406     SaveStringToFd(rawParamFd_, lostTitle + to_string(ram.lost) + MemoryUtil::GetInstance().KB_UNIT_ + "\n");
407 }
408 
GetPurgTotal(const ValueMap & meminfo,StringMatrix result)409 void MemoryInfo::GetPurgTotal(const ValueMap &meminfo, StringMatrix result)
410 {
411     SaveStringToFd(rawParamFd_, "Total Purgeable:\n");
412 
413     uint64_t purgSumTotal = 0;
414     uint64_t purgPinTotal = 0;
415     auto purgSumActive = meminfo.find(MemoryFilter::GetInstance().PURG_SUM[0]);
416     auto purgSumInactive = meminfo.find(MemoryFilter::GetInstance().PURG_SUM[1]);
417     auto purgPinPined = meminfo.find(MemoryFilter::GetInstance().PURG_PIN[0]);
418     if (purgSumActive == meminfo.end() || purgSumInactive == meminfo.end() || purgPinPined == meminfo.end()) {
419         DUMPER_HILOGE(MODULE_SERVICE, "fail to get purg info \n");
420     } else {
421         purgSumTotal = purgSumActive->second + purgSumInactive->second;
422         purgPinTotal = purgPinPined->second;
423     }
424 
425     string totalPurgSumTitle = "Total PurgSum:";
426     StringUtils::GetInstance().SetWidth(RAM_WIDTH_, BLANK_, false, totalPurgSumTitle);
427     SaveStringToFd(rawParamFd_, totalPurgSumTitle + AddKbUnit(purgSumTotal) + "\n");
428 
429     string totalPurgPinTitle = "Total PurgPin:";
430     StringUtils::GetInstance().SetWidth(RAM_WIDTH_, BLANK_, false, totalPurgPinTitle);
431     SaveStringToFd(rawParamFd_, totalPurgPinTitle + AddKbUnit(purgPinTotal) + "\n");
432 }
433 
GetPurgByPid(const int32_t & pid,StringMatrix result)434 void MemoryInfo::GetPurgByPid(const int32_t &pid, StringMatrix result)
435 {
436     AddBlankLine(result);
437     vector<string> title;
438     title.push_back("Purgeable:");
439     result->push_back(title);
440 
441     vector<string> purgSum;
442     string purgSumTitle = MemoryFilter::GetInstance().PURGSUM_OUT_LABEL + ":";
443     StringUtils::GetInstance().SetWidth(RAM_WIDTH_, BLANK_, false, purgSumTitle);
444     purgSum.push_back(purgSumTitle);
445     purgSum.push_back(AddKbUnit(GetProcValue(pid, MemoryFilter::GetInstance().PURGSUM_OUT_LABEL)));
446     result->push_back(purgSum);
447 
448     vector<string> purgPin;
449     string purgPinTitle = MemoryFilter::GetInstance().PURGPIN_OUT_LABEL + ":";
450     StringUtils::GetInstance().SetWidth(RAM_WIDTH_, BLANK_, false, purgPinTitle);
451     purgPin.push_back(purgPinTitle);
452     purgPin.push_back(AddKbUnit(GetProcValue(pid, MemoryFilter::GetInstance().PURGPIN_OUT_LABEL)));
453     result->push_back(purgPin);
454 }
455 
GetNativeValue(const string & tag,const GroupMap & nativeGroupMap,StringMatrix result)456 void MemoryInfo::GetNativeValue(const string& tag, const GroupMap& nativeGroupMap, StringMatrix result)
457 {
458     vector<string> heap;
459     string heapTitle = tag + ":";
460     StringUtils::GetInstance().SetWidth(RAM_WIDTH_, BLANK_, false, heapTitle);
461     heap.push_back(heapTitle);
462 
463     auto info = nativeGroupMap.find(tag);
464     if (info == nativeGroupMap.end()) {
465         DUMPER_HILOGE(MODULE_SERVICE, "GetNativeValue fail! tag = %{public}s", tag.c_str());
466         return;
467     }
468     string nativeValue;
469     auto &valueMap = info->second;
470     for (const auto &key : MemoryFilter::GetInstance().VALUE_WITH_PID) {
471         auto it = valueMap.find(key);
472         string value = "0";
473         if (it != valueMap.end()) {
474             value = to_string(it->second);
475         }
476         StringUtils::GetInstance().SetWidth(LINE_WIDTH_, BLANK_, false, value);
477         nativeValue += value + BLANK_;
478     }
479 
480     heap.push_back(nativeValue);
481     result->push_back(heap);
482 }
483 
GetNativeHeap(const GroupMap & nativeGroupMap,StringMatrix result)484 void MemoryInfo::GetNativeHeap(const GroupMap& nativeGroupMap, StringMatrix result)
485 {
486     AddBlankLine(result);
487     vector<string> title;
488     title.push_back(MemoryFilter::GetInstance().NATIVE_HEAP_LABEL + ":");
489     result->push_back(title);
490     for (const auto &it: NATIVE_HEAP_TAG_) {
491         GetNativeValue(it, nativeGroupMap, result);
492     }
493 }
494 
GetDmaByPid(MemInfoData::GraphicsMemory & graphicsMemory,StringMatrix result)495 void MemoryInfo::GetDmaByPid(MemInfoData::GraphicsMemory& graphicsMemory, StringMatrix result)
496 {
497     AddBlankLine(result);
498     vector<string> title;
499     title.push_back(MemoryFilter::GetInstance().DMA_TAG + ":");
500     result->push_back(title);
501 
502     vector<string> dma;
503     string dmaTitle = MemoryFilter::GetInstance().DMA_OUT_LABEL + ":";
504     StringUtils::GetInstance().SetWidth(RAM_WIDTH_, BLANK_, false, dmaTitle);
505     dma.push_back(dmaTitle);
506     dma.push_back(to_string(graphicsMemory.graph) + MemoryUtil::GetInstance().KB_UNIT_);
507     result->push_back(dma);
508 }
509 
GetHiaiServerIon(const int32_t & pid,StringMatrix result)510 void MemoryInfo::GetHiaiServerIon(const int32_t &pid, StringMatrix result)
511 {
512     if (GetProcName(pid) != "hiaiserver") {
513         return;
514     }
515     void *handle = dlopen(LIB.c_str(), RTLD_LAZY);
516     if (handle == nullptr) {
517         DUMPER_HILOGE(MODULE_SERVICE, "fail to open %{public}s.", LIB.c_str());
518         return;
519     }
520     HiaiFunc pfn = reinterpret_cast<HiaiFunc>(dlsym(handle, HIAI_MEM_INFO_FN));
521     if (pfn == nullptr) {
522         DUMPER_HILOGE(MODULE_SERVICE, "fail to dlsym %{public}s.", HIAI_MEM_INFO_FN);
523         dlclose(handle);
524         return;
525     }
526     MemInfoData::HiaiUserAllocatedMemInfo memInfos[HIAI_MAX_QUERIED_USER_MEMINFO_LIMIT] = {};
527 
528     int realSize = 0;
529     pfn(memInfos, HIAI_MAX_QUERIED_USER_MEMINFO_LIMIT, &realSize);
530     if (realSize > 0) {
531         AddBlankLine(result);
532         vector<string> vecIon;
533         vecIon.push_back("HIAIServer ION:\n");
534         for (int i = 0; i < realSize; i++) {
535             vecIon.push_back(GetProcName(memInfos[i].pid) + "(" + to_string(memInfos[i].pid) + "):" +
536                              to_string(memInfos[i].size / BYTE_PER_KB) + " kB\n");
537         }
538         result->push_back(vecIon);
539     }
540     dlclose(handle);
541 }
542 
GetRamCategory(const GroupMap & smapsInfos,const ValueMap & meminfos,StringMatrix result)543 void MemoryInfo::GetRamCategory(const GroupMap &smapsInfos, const ValueMap &meminfos, StringMatrix result)
544 {
545     SaveStringToFd(rawParamFd_, "Total RAM by Category:\n");
546 
547     bool hardWareSuccess = GetHardWareUsage(result);
548     if (!hardWareSuccess) {
549         DUMPER_HILOGE(MODULE_SERVICE, "Get hardWare usage fail.\n");
550     }
551 
552     bool cmaSuccess = GetCMAUsage(result);
553     if (!cmaSuccess) {
554         DUMPER_HILOGE(MODULE_SERVICE, "Get CMA fail.\n");
555     }
556 
557     bool kernelSuccess = GetKernelUsage(meminfos, result);
558     if (!kernelSuccess) {
559         DUMPER_HILOGE(MODULE_SERVICE, "Get kernel usage fail.\n");
560     }
561 
562     GetProcesses(smapsInfos, result);
563 }
564 
AddBlankLine(StringMatrix result)565 void MemoryInfo::AddBlankLine(StringMatrix result)
566 {
567     vector<string> blank;
568     blank.push_back("\n");
569     result->push_back(blank);
570 }
571 
GetProcName(const int32_t & pid)572 string MemoryInfo::GetProcName(const int32_t &pid)
573 {
574     string procName = UNKNOWN_PROCESS;
575     DumpCommonUtils::GetProcessNameByPid(pid, procName);
576     if (procName == UNKNOWN_PROCESS) {
577         string path = "/proc/" + to_string(pid) + "/status";
578         procName = FileUtils::GetInstance().GetProcValue(pid, path, "Name");
579     }
580     return procName;
581 }
582 
GetProcValue(const int32_t & pid,const string & key)583 uint64_t MemoryInfo::GetProcValue(const int32_t &pid, const string& key)
584 {
585     string path = "/proc/" + to_string(pid) + "/status";
586     std::string value = FileUtils::GetInstance().GetProcValue(pid, path, key);
587     if (value == UNKNOWN_PROCESS) {
588         DUMPER_HILOGE(MODULE_SERVICE, "GetProcStatusValue failed");
589         return 0;
590     }
591     int number = 0;
592     value = value.substr(0, value.size() - 3); // 3: ' kB'
593     if (value.find_last_of(' ') != std::string::npos) {
594         value = value.substr(value.find_last_of(' ') + 1);
595     }
596     if (!StrToInt(value, number)) {
597         DUMPER_HILOGE(MODULE_COMMON, "StrToInt failed, value: %{public}s", value.c_str());
598         return 0;
599     }
600     return static_cast<uint64_t>(number);
601 }
602 
GetProcessAdjLabel(const int32_t pid)603 string MemoryInfo::GetProcessAdjLabel(const int32_t pid)
604 {
605     string adjLabel = RECLAIM_PRIORITY_UNKNOWN_DESC;
606     string fillPath = "/proc/" + to_string(pid) + "/oom_score_adj";
607     if (!DumpUtils::PathIsValid(fillPath)) {
608         DUMPER_HILOGE(MODULE_COMMON, "GetProcessAdjLabel leave|false, PathIsValid");
609         return adjLabel;
610     }
611     auto fp = fopen(fillPath.c_str(), "rb");
612     if (fp == nullptr) {
613         DUMPER_HILOGE(MODULE_COMMON, "Open oom_score_adj failed.");
614         return adjLabel;
615     }
616     constexpr int bufSize = 128; // 128: buf size
617     char buf[bufSize] = {0};
618     size_t readSum = fread(buf, 1, bufSize, fp);
619     (void)fclose(fp);
620     fp = nullptr;
621     if (readSum < 1) {
622         DUMPER_HILOGE(MODULE_COMMON, "Read oom_score_adj failed.");
623         return adjLabel;
624     }
625     int value = RECLAIM_PRIORITY_UNKNOWN;
626     std::string label(buf);
627     if (label.empty()) {
628         DUMPER_HILOGE(MODULE_COMMON, "label is empty.");
629         return adjLabel;
630     }
631     if (!StrToInt(label.substr(0, label.size() - 1), value)) {
632         DUMPER_HILOGE(MODULE_COMMON, "StrToInt failed.");
633         return adjLabel;
634     }
635     adjLabel = GetReclaimPriorityString(value);
636     return adjLabel;
637 }
638 
GetPids()639 bool MemoryInfo::GetPids()
640 {
641     bool success = DumpCommonUtils::GetUserPids(pids_);
642     if (!success) {
643         DUMPER_HILOGE(MODULE_SERVICE, "GetPids error");
644     }
645     return success;
646 }
647 
GetVss(const int32_t & pid)648 uint64_t MemoryInfo::GetVss(const int32_t &pid)
649 {
650     string path = "/proc/" + to_string(pid) + "/statm";
651     uint64_t res = 0;
652     bool ret = FileUtils::GetInstance().LoadStringFromProcCb(path, true, true, [&](const string& line) -> void {
653         if (!line.empty()) {
654             uint64_t tempValue = 0;
655             int retScanf = sscanf_s(line.c_str(), "%llu^*", &tempValue);
656             if (retScanf != -1) {
657                 res = tempValue * VSS_BIT;
658             } else {
659                 DUMPER_HILOGE(MODULE_SERVICE, "GetVss error! pid = %{public}d", pid);
660             }
661         }
662     });
663     if (!ret) {
664         return 0;
665     }
666     return res;
667 }
668 
GetGraphicsMemory(int32_t pid,MemInfoData::GraphicsMemory & graphicsMemory,GraphicType graphicType)669 bool MemoryInfo::GetGraphicsMemory(int32_t pid, MemInfoData::GraphicsMemory& graphicsMemory, GraphicType graphicType)
670 {
671     std::shared_ptr<UCollectUtil::GraphicMemoryCollector> collector = UCollectUtil::GraphicMemoryCollector::Create();
672     CollectResult<int32_t> data;
673     data = collector->GetGraphicUsage(pid, graphicType);
674     if (data.retCode != UCollect::UcError::SUCCESS) {
675         DUMPER_HILOGE(MODULE_SERVICE, "collect progress GL or Graph error, ret:%{public}d", data.retCode);
676         return false;
677     }
678     if (graphicType == GraphicType::GL) {
679         graphicsMemory.gl = static_cast<uint64_t>(data.data);
680     } else if (graphicType == GraphicType::GRAPH) {
681         graphicsMemory.graph = static_cast<uint64_t>(data.data);
682     } else {
683         DUMPER_HILOGE(MODULE_SERVICE, "graphic type is not support.");
684         return false;
685     }
686     return true;
687 }
688 
GetMemByProcessPid(const int32_t & pid,MemInfoData::MemUsage & usage)689 bool MemoryInfo::GetMemByProcessPid(const int32_t& pid, MemInfoData::MemUsage& usage)
690 {
691     bool success = false;
692     MemInfoData::MemInfo memInfo;
693     unique_ptr<ParseSmapsRollupInfo> getSmapsRollup = make_unique<ParseSmapsRollupInfo>();
694     if (getSmapsRollup->GetMemInfo(pid, memInfo)) {
695         usage.vss = GetVss(pid);
696         usage.uss = memInfo.privateClean + memInfo.privateDirty;
697         usage.rss = memInfo.rss;
698         usage.pss = memInfo.pss;
699         usage.swapPss = memInfo.swapPss;
700         usage.name = GetProcName(pid);
701         usage.pid = pid;
702         usage.adjLabel = GetProcessAdjLabel(pid);
703         success = true;
704     }
705 
706     MemInfoData::GraphicsMemory graphicsMemory;
707     MemoryUtil::GetInstance().InitGraphicsMemory(graphicsMemory);
708     if (GetGraphicsMemory(pid, graphicsMemory, GraphicType::GL)) {
709         usage.gl = graphicsMemory.gl;
710         usage.uss = usage.uss + graphicsMemory.gl;
711         usage.pss = usage.pss + graphicsMemory.gl;
712         usage.rss = usage.rss + graphicsMemory.gl;
713     }
714     if (GetGraphicsMemory(pid, graphicsMemory, GraphicType::GRAPH)) {
715         usage.graph = graphicsMemory.graph;
716         usage.dma = graphicsMemory.graph;
717         usage.uss = usage.uss + graphicsMemory.graph;
718         usage.pss = usage.pss + graphicsMemory.graph;
719         usage.rss = usage.rss + graphicsMemory.graph;
720         DUMPER_HILOGD(MODULE_SERVICE, "uss:%{public}d pss:%{public}d rss:%{public}d gl:%{public}d graph:%{public}d",
721                       static_cast<int>(usage.uss), static_cast<int>(usage.pss), static_cast<int>(usage.rss),
722                       static_cast<int>(graphicsMemory.gl), static_cast<int>(graphicsMemory.graph));
723     }
724     return success;
725 }
726 
MemUsageToMatrix(const MemInfoData::MemUsage & memUsage,StringMatrix result)727 void MemoryInfo::MemUsageToMatrix(const MemInfoData::MemUsage &memUsage, StringMatrix result)
728 {
729     string pid = to_string(memUsage.pid);
730     StringUtils::GetInstance().SetWidth(PID_WIDTH_, BLANK_, true, pid);
731 
732     uint64_t pss = memUsage.pss + memUsage.swapPss;
733     string totalPss = to_string(pss) + "(" + to_string(memUsage.swapPss) + " in SwapPss) kB";
734     StringUtils::GetInstance().SetWidth(PSS_WIDTH_, BLANK_, false, totalPss);
735 
736     uint64_t vss = memUsage.vss;
737     string totalVss = AddKbUnit(vss);
738     StringUtils::GetInstance().SetWidth(KB_WIDTH_, BLANK_, false, totalVss);
739 
740     uint64_t rss = memUsage.rss;
741     string totalRss = AddKbUnit(rss);
742     StringUtils::GetInstance().SetWidth(KB_WIDTH_, BLANK_, false, totalRss);
743 
744     uint64_t uss = memUsage.uss;
745     string totalUss = AddKbUnit(uss);
746     StringUtils::GetInstance().SetWidth(KB_WIDTH_, BLANK_, false, totalUss);
747 
748     uint64_t gl = memUsage.gl;
749     string unMappedGL = AddKbUnit(gl);
750     StringUtils::GetInstance().SetWidth(KB_WIDTH_, BLANK_, false, unMappedGL);
751 
752     uint64_t graph = memUsage.graph;
753     string unMappedGraph = AddKbUnit(graph);
754     StringUtils::GetInstance().SetWidth(KB_WIDTH_, BLANK_, false, unMappedGraph);
755 
756     uint64_t dma = memUsage.dma;
757     string unMappedDma = AddKbUnit(dma);
758     StringUtils::GetInstance().SetWidth(KB_WIDTH_, BLANK_, false, unMappedDma);
759 
760     uint64_t purgSum = memUsage.purgSum;
761     string unMappedPurgSum = AddKbUnit(purgSum);
762     StringUtils::GetInstance().SetWidth(KB_WIDTH_, BLANK_, false, unMappedPurgSum);
763 
764     uint64_t purgPin = memUsage.purgPin;
765     string unMappedPurgPin = AddKbUnit(purgPin);
766     StringUtils::GetInstance().SetWidth(KB_WIDTH_, BLANK_, false, unMappedPurgPin);
767 
768     string name = "    " + memUsage.name;
769     StringUtils::GetInstance().SetWidth(NAME_WIDTH_, BLANK_, true, name);
770 
771     (void)dprintf(rawParamFd_, "%s %s %s %s %s %s %s %s %s %s %s\n", pid.c_str(),
772         totalPss.c_str(), totalVss.c_str(), totalRss.c_str(), totalUss.c_str(),
773         unMappedGL.c_str(), unMappedGraph.c_str(), unMappedDma.c_str(), unMappedPurgSum.c_str(),
774         unMappedPurgPin.c_str(), name.c_str());
775 }
776 
AddMemByProcessTitle(StringMatrix result,string sortType)777 void MemoryInfo::AddMemByProcessTitle(StringMatrix result, string sortType)
778 {
779     string processTitle = "Total Memory Usage by " + sortType + ":";
780     (void)dprintf(rawParamFd_, "%s\n", processTitle.c_str());
781 
782     string pid = "PID";
783     StringUtils::GetInstance().SetWidth(PID_WIDTH_, BLANK_, true, pid);
784 
785     string totalPss = "Total Pss(xxx in SwapPss)";
786     StringUtils::GetInstance().SetWidth(PSS_WIDTH_, BLANK_, false, totalPss);
787 
788     string totalVss = "Total Vss";
789     StringUtils::GetInstance().SetWidth(KB_WIDTH_, BLANK_, false, totalVss);
790 
791     string totalRss = "Total Rss";
792     StringUtils::GetInstance().SetWidth(KB_WIDTH_, BLANK_, false, totalRss);
793 
794     string totalUss = "Total Uss";
795     StringUtils::GetInstance().SetWidth(KB_WIDTH_, BLANK_, false, totalUss);
796 
797     string unMappedGL = MemoryFilter::GetInstance().GL_OUT_LABEL;
798     StringUtils::GetInstance().SetWidth(KB_WIDTH_, BLANK_, false, unMappedGL);
799 
800     string unMappedGraph = MemoryFilter::GetInstance().GRAPH_OUT_LABEL;
801     StringUtils::GetInstance().SetWidth(KB_WIDTH_, BLANK_, false, unMappedGraph);
802 
803     string unMappedDma = MemoryFilter::GetInstance().DMA_OUT_LABEL;
804     StringUtils::GetInstance().SetWidth(KB_WIDTH_, BLANK_, false, unMappedDma);
805 
806     string unMappedPurgSum = MemoryFilter::GetInstance().PURGSUM_OUT_LABEL;
807     StringUtils::GetInstance().SetWidth(KB_WIDTH_, BLANK_, false, unMappedPurgSum);
808 
809     string unMappedPurgPin = MemoryFilter::GetInstance().PURGPIN_OUT_LABEL;
810     StringUtils::GetInstance().SetWidth(KB_WIDTH_, BLANK_, false, unMappedPurgPin);
811 
812     string name = "    Name";
813     StringUtils::GetInstance().SetWidth(NAME_WIDTH_, BLANK_, true, name);
814 
815     (void)dprintf(rawParamFd_, "%s %s %s %s %s %s %s %s %s %s %s\n", pid.c_str(),
816         totalPss.c_str(), totalVss.c_str(), totalRss.c_str(), totalUss.c_str(),
817         unMappedGL.c_str(), unMappedGraph.c_str(), unMappedDma.c_str(), unMappedPurgSum.c_str(),
818         unMappedPurgPin.c_str(), name.c_str());
819 }
820 
GetMemoryInfoNoPid(int fd,StringMatrix result)821 DumpStatus MemoryInfo::GetMemoryInfoNoPid(int fd, StringMatrix result)
822 {
823     std::lock_guard<std::mutex> lock(mutex_);
824     rawParamFd_ = fd;
825     (void)dprintf(rawParamFd_, "%s\n", MEMORY_LINE.c_str());
826     if (!isReady_) {
827         memUsages_.clear();
828         pids_.clear();
829         totalGL_ = 0;
830         totalGraph_ = 0;
831         AddMemByProcessTitle(result, "PID");
832         if (!GetPids()) {
833             return DUMP_FAIL;
834         }
835         isReady_ = true;
836     }
837 
838     if (!dumpSmapsOnStart_) {
839         dumpSmapsOnStart_ = true;
840         std::promise<GroupMap> promise;
841         fut_ = promise.get_future();
842         std::thread([promise = std::move(promise), this]() mutable {
843             GroupMap groupMap;
844             std::vector<int32_t> pids(this->pids_);
845             for (auto pid : pids) {
846                 GetSmapsInfoNoPid(pid, groupMap);
847             }
848             promise.set_value(groupMap);
849             }).detach();
850     }
851     MemInfoData::MemUsage usage;
852     MemoryUtil::GetInstance().InitMemUsage(usage);
853     for (auto pid : pids_) {
854         if (GetMemByProcessPid(pid, usage)) {
855             memUsages_.push_back(usage);
856             adjMemResult_[usage.adjLabel].push_back(usage);
857             totalGL_ += usage.gl;
858             totalGraph_ += usage.graph;
859             totalDma_ += usage.dma;
860             MemUsageToMatrix(usage, result);
861         } else {
862             DUMPER_HILOGE(MODULE_SERVICE, "Get smaps_rollup error! pid = %{public}d\n", static_cast<int>(pid));
863         }
864     }
865     return DealResult(result);
866 }
867 
DealResult(StringMatrix result)868 DumpStatus MemoryInfo::DealResult(StringMatrix result)
869 {
870     ValueMap meminfoResult;
871     if (!GetMeminfo(meminfoResult)) {
872         DUMPER_HILOGE(MODULE_SERVICE, "Get meminfo error\n");
873         return DUMP_FAIL;
874     }
875 
876     GetSortedMemoryInfoNoPid(result);
877     SaveStringToFd(rawParamFd_, "\n");
878     GetMemoryByAdj(result);
879     SaveStringToFd(rawParamFd_, "\n");
880 
881     GroupMap smapsResult = fut_.get();
882 
883     GetPssTotal(smapsResult, result);
884     SaveStringToFd(rawParamFd_, "\n");
885 
886     GetRamUsage(smapsResult, meminfoResult, result);
887     SaveStringToFd(rawParamFd_, "\n");
888 
889     GetRamCategory(smapsResult, meminfoResult, result);
890     SaveStringToFd(rawParamFd_, "\n");
891 
892     GetPurgTotal(meminfoResult, result);
893 
894     isReady_ = false;
895     dumpSmapsOnStart_ = false;
896     memUsages_.clear();
897     smapsResult.clear();
898     return DUMP_OK;
899 }
900 
GetSortedMemoryInfoNoPid(StringMatrix result)901 void MemoryInfo::GetSortedMemoryInfoNoPid(StringMatrix result)
902 {
903     SaveStringToFd(rawParamFd_, "\n");
904     AddMemByProcessTitle(result, "Size");
905 
906     std::sort(memUsages_.begin(), memUsages_.end(),
907         [] (MemInfoData::MemUsage &left, MemInfoData::MemUsage &right) {
908         if (right.pss + right.swapPss != left.pss + left.swapPss) {
909             return right.pss + right.swapPss < left.pss + left.swapPss;
910         }
911         if (right.vss != left.vss) {
912             return right.vss < left.vss;
913         }
914         if (right.rss != left.rss) {
915             return right.rss < left.rss;
916         }
917         if (right.uss != left.uss) {
918             return right.uss < left.uss;
919         }
920         return right.pid < left.pid;
921     });
922 
923     for (auto &memUsage : memUsages_) {
924         MemUsageToMatrix(memUsage, result);
925     }
926 }
927 
GetMemoryByAdj(StringMatrix result)928 void MemoryInfo::GetMemoryByAdj(StringMatrix result)
929 {
930     SaveStringToFd(rawParamFd_, "Total Pss by OOM adjustment:\n");
931 
932     vector<string> reclaimPriority_;
933     for (auto reclaim : ReclaimPriorityMapping) {
934         reclaimPriority_.push_back(reclaim.second);
935     }
936     reclaimPriority_.push_back(RECLAIM_PRIORITY_UNKNOWN_DESC);
937 
938     for (const auto &adjLabel : reclaimPriority_) {
939         vector<MemInfoData::MemUsage> memUsages = adjMemResult_[adjLabel];
940         vector<string> label;
941         if (memUsages.size() == 0) {
942             SaveStringToFd(rawParamFd_, adjLabel + ": " + AddKbUnit(0) + "\n");
943             continue;
944         }
945         uint64_t totalPss = accumulate(memUsages.begin(), memUsages.end(), (uint64_t)0,
946         [] (uint64_t a, MemInfoData::MemUsage &b) {
947             return a + b.pss + b.swapPss;
948         });
949         SaveStringToFd(rawParamFd_, adjLabel + ": " + AddKbUnit(totalPss) + "\n");
950 
951         std::sort(memUsages.begin(), memUsages.end(),
952             [] (MemInfoData::MemUsage &left, MemInfoData::MemUsage &right) {
953             return right.pss + right.swapPss < left.pss + left.swapPss;
954         });
955         for (const auto &memUsage : memUsages) {
956             string name = PRE_BLANK + memUsage.name + "(pid=" + to_string(memUsage.pid) + "): ";
957             StringUtils::GetInstance().SetWidth(NAME_AND_PID_WIDTH, BLANK_, true, name);
958             name += AddKbUnit(memUsage.pss + memUsage.swapPss);
959             if (memUsage.swapPss > 0) {
960                 name += " (" + to_string(memUsage.swapPss) + " kB in SwapPss)";
961             }
962             SaveStringToFd(rawParamFd_, name + "\n");
963         }
964     }
965 }
966 
GetReclaimPriorityString(int32_t priority)967 std::string MemoryInfo::GetReclaimPriorityString(int32_t priority)
968 {
969     if (priority < RECLAIM_PRIORITY_SYSTEM || priority > RECLAIM_PRIORITY_UNKNOWN) {
970         return RECLAIM_PRIORITY_UNKNOWN_DESC;
971     } else if (priority < RECLAIM_ONDEMAND_SYSTEM) {
972         return ReclaimPriorityMapping.at(RECLAIM_PRIORITY_SYSTEM);
973     } else if (priority < RECLAIM_PRIORITY_KILLABLE_SYSTEM) {
974         return ReclaimPriorityMapping.at(RECLAIM_ONDEMAND_SYSTEM);
975     } else if (priority < RECLAIM_PRIORITY_FOREGROUND) {
976         return ReclaimPriorityMapping.at(RECLAIM_PRIORITY_KILLABLE_SYSTEM);
977     } else if (priority < RECLAIM_PRIORITY_VISIBLE) {
978         return ReclaimPriorityMapping.at(RECLAIM_PRIORITY_FOREGROUND);
979     } else if (priority < RECLAIM_PRIORITY_BG_SUSPEND_DELAY) {
980         return ReclaimPriorityMapping.at(RECLAIM_PRIORITY_VISIBLE);
981     } else if (priority < RECLAIM_PRIORITY_BG_PERCEIVED) {
982         return ReclaimPriorityMapping.at(RECLAIM_PRIORITY_BG_SUSPEND_DELAY);
983     } else if (priority < RECLAIM_PRIORITY_BG_DIST_DEVICE) {
984         return ReclaimPriorityMapping.at(RECLAIM_PRIORITY_BG_PERCEIVED);
985     } else if (priority < RECLAIM_PRIORITY_BACKGROUND) {
986         return ReclaimPriorityMapping.at(RECLAIM_PRIORITY_BG_DIST_DEVICE);
987     } else {
988         return ReclaimPriorityMapping.at(RECLAIM_PRIORITY_BACKGROUND);
989     }
990 }
991 
SetPss(MemInfoData::MemInfo & meminfo,uint64_t value)992 void MemoryInfo::SetPss(MemInfoData::MemInfo &meminfo, uint64_t value)
993 {
994     meminfo.pss += value;
995 }
996 
SetSharedClean(MemInfoData::MemInfo & meminfo,uint64_t value)997 void MemoryInfo::SetSharedClean(MemInfoData::MemInfo &meminfo, uint64_t value)
998 {
999     meminfo.sharedClean += value;
1000 }
1001 
SetSharedDirty(MemInfoData::MemInfo & meminfo,uint64_t value)1002 void MemoryInfo::SetSharedDirty(MemInfoData::MemInfo &meminfo, uint64_t value)
1003 {
1004     meminfo.sharedDirty += value;
1005 }
1006 
SetPrivateClean(MemInfoData::MemInfo & meminfo,uint64_t value)1007 void MemoryInfo::SetPrivateClean(MemInfoData::MemInfo &meminfo, uint64_t value)
1008 {
1009     meminfo.privateClean += value;
1010 }
1011 
SetPrivateDirty(MemInfoData::MemInfo & meminfo,uint64_t value)1012 void MemoryInfo::SetPrivateDirty(MemInfoData::MemInfo &meminfo, uint64_t value)
1013 {
1014     meminfo.privateDirty += value;
1015 }
1016 
SetSwap(MemInfoData::MemInfo & meminfo,uint64_t value)1017 void MemoryInfo::SetSwap(MemInfoData::MemInfo &meminfo, uint64_t value)
1018 {
1019     meminfo.swap += value;
1020 }
1021 
SetSwapPss(MemInfoData::MemInfo & meminfo,uint64_t value)1022 void MemoryInfo::SetSwapPss(MemInfoData::MemInfo &meminfo, uint64_t value)
1023 {
1024     meminfo.swapPss += value;
1025 }
SetHeapSize(MemInfoData::MemInfo & meminfo,uint64_t value)1026 void MemoryInfo::SetHeapSize(MemInfoData::MemInfo &meminfo, uint64_t value)
1027 {
1028     meminfo.heapSize += value;
1029 }
1030 
SetHeapAlloc(MemInfoData::MemInfo & meminfo,uint64_t value)1031 void MemoryInfo::SetHeapAlloc(MemInfoData::MemInfo &meminfo, uint64_t value)
1032 {
1033     meminfo.heapAlloc += value;
1034 }
1035 
SetHeapFree(MemInfoData::MemInfo & meminfo,uint64_t value)1036 void MemoryInfo::SetHeapFree(MemInfoData::MemInfo &meminfo, uint64_t value)
1037 {
1038     meminfo.heapFree += value;
1039 }
1040 } // namespace HiviewDFX
1041 } // namespace OHOS
1042