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 #ifndef MEMORY_INFO_H
16 #define MEMORY_INFO_H
17 #include <future>
18 #include <map>
19 #include <memory>
20 #include <mutex>
21 #include <string>
22 #include <vector>
23 #include "executor/memory/dma_info.h"
24 #include "executor/memory/parse/meminfo_data.h"
25 #include "common.h"
26 #include "time.h"
27 #include "graphic_memory_collector.h"
28 namespace OHOS {
29 namespace HiviewDFX {
30 namespace {
31 static const std::string MEMINFO_PSS = "Pss";
32 static const std::string MEMINFO_SHARED_CLEAN = "Shared_Clean";
33 static const std::string MEMINFO_SHARED_DIRTY = "Shared_Dirty";
34 static const std::string MEMINFO_PRIVATE_CLEAN = "Private_Clean";
35 static const std::string MEMINFO_PRIVATE_DIRTY = "Private_Dirty";
36 static const std::string MEMINFO_SWAP = "Swap";
37 static const std::string MEMINFO_SWAP_PSS = "SwapPss";
38 static const std::string MEMINFO_HEAP_SIZE = "Heap_Size";
39 static const std::string MEMINFO_HEAP_ALLOC = "Heap_Alloc";
40 static const std::string MEMINFO_HEAP_FREE = "Heap_Free";
41 static const std::string MEMINFO_DMA = "Dma";
42 
43 // system app
44 constexpr int RECLAIM_PRIORITY_SYSTEM = -1000;
45 //ondemand system app
46 constexpr int RECLAIM_ONDEMAND_SYSTEM = -900;
47 // persist(killable) system app
48 constexpr int RECLAIM_PRIORITY_KILLABLE_SYSTEM = -800;
49 // foreground process priority
50 constexpr int RECLAIM_PRIORITY_FOREGROUND = 0;
51 // visible process priority
52 constexpr int RECLAIM_PRIORITY_VISIBLE = 50;
53 // perceived suspend delay case
54 constexpr int RECLAIM_PRIORITY_BG_SUSPEND_DELAY = 100;
55 // perceived background process priority
56 constexpr int RECLAIM_PRIORITY_BG_PERCEIVED = 200;
57 // background and connected by distribute device
58 constexpr int RECLAIM_PRIORITY_BG_DIST_DEVICE = 260;
59 // background priority
60 constexpr int RECLAIM_PRIORITY_BACKGROUND = 400;
61 // unknown process priority
62 constexpr int RECLAIM_PRIORITY_UNKNOWN = 1000;
63 
64 const std::map<int, std::string> ReclaimPriorityMapping = {
65     { RECLAIM_PRIORITY_SYSTEM, "System" },
66     { RECLAIM_ONDEMAND_SYSTEM, "OnDemand_system" },
67     { RECLAIM_PRIORITY_KILLABLE_SYSTEM, "Persistent" },
68     { RECLAIM_PRIORITY_FOREGROUND, "Foreground" },
69     { RECLAIM_PRIORITY_VISIBLE, "visible" },
70     { RECLAIM_PRIORITY_BG_SUSPEND_DELAY, "Suspend-delay" },
71     { RECLAIM_PRIORITY_BG_PERCEIVED, "Perceived" },
72     { RECLAIM_PRIORITY_BG_DIST_DEVICE, "Dist-device" },
73     { RECLAIM_PRIORITY_BACKGROUND, "Background" },
74 };
75 
76 const std::string RECLAIM_PRIORITY_UNKNOWN_DESC = "Undefined";
77 }
78 class MemoryInfo {
79 public:
80     MemoryInfo();
81     ~MemoryInfo();
82 
83     using StringMatrix = std::shared_ptr<std::vector<std::vector<std::string>>>;
84     using ValueMap = std::map<std::string, uint64_t>;
85     using GroupMap = std::map<std::string, ValueMap>;
86     using MemFun = std::function<void(MemInfoData::MemInfo&, uint64_t)>;
87 
88     bool GetMemoryInfoByPid(const int32_t &pid, StringMatrix result);
89     DumpStatus GetMemoryInfoNoPid(int fd, StringMatrix result);
90     DumpStatus DealResult(StringMatrix result);
91 
92 private:
93     enum Status {
94         SUCCESS_MORE_DATA = 1,
95         FAIL_MORE_DATA = 2,
96         SUCCESS_NO_MORE_DATA = 3,
97         FAIL_NO_MORE_DATA = 4,
98     };
99     int rawParamFd_ = 0;
100     const int LINE_WIDTH_ = 14;
101     const int RAM_WIDTH_ = 16;
102     const size_t TYPE_SIZE = 2;
103     const char SEPARATOR_ = '-';
104     const char BLANK_ = ' ';
105     const static int NAME_SIZE_ = 2;
106     const int PID_WIDTH_ = 5;
107     const int NAME_WIDTH_ = 20;
108     const int PSS_WIDTH_ = 30;
109     const int KB_WIDTH_ = 12;
110     const int NAME_AND_PID_WIDTH = 30;
111     const static int VSS_BIT = 4;
112     const static int BYTE_PER_KB = 1024;
113     bool isReady_ = false;
114     bool dumpSmapsOnStart_ = false;
115     uint64_t totalGL_ = 0;
116     uint64_t totalGraph_ = 0;
117     uint64_t totalDma_ = 0;
118     std::mutex mutex_;
119     std::future<GroupMap> fut_;
120     std::vector<int32_t> pids_;
121     std::vector<MemInfoData::MemUsage> memUsages_;
122     std::vector<std::pair<std::string, MemFun>> methodVec_;
123     std::map<std::string, std::vector<MemInfoData::MemUsage>> adjMemResult_ = {
124         {"System", {}}, {"Foreground", {}}, {"Suspend-delay", {}},
125         {"Perceived", {}}, {"Background", {}}, {"Undefined", {}},
126     };
127     std::vector<std::string> NATIVE_HEAP_TAG_ = {"heap", "jemalloc meta", "jemalloc heap",
128                                                  "brk heap", "musl heap", "mmap heap"};
129     DmaInfo dmaInfo_;
130     void insertMemoryTitle(StringMatrix result);
131     void BuildResult(const GroupMap &infos, StringMatrix result);
132 
133     std::string AddKbUnit(const uint64_t &value) const;
134     bool GetMemByProcessPid(const int32_t& pid, MemInfoData::MemUsage& usage);
135     static bool GetSmapsInfoNoPid(const int32_t &pid, GroupMap &result);
136     bool GetMeminfo(ValueMap &result);
137     bool GetHardWareUsage(StringMatrix result);
138     bool GetCMAUsage(StringMatrix result);
139     bool GetKernelUsage(const ValueMap &infos, StringMatrix result);
140     void GetProcesses(const GroupMap &infos, StringMatrix result);
141     bool GetPids();
142     void GetPssTotal(const GroupMap &infos, StringMatrix result);
143     void GetRamUsage(const GroupMap &smapsinfos, const ValueMap &meminfo, StringMatrix result);
144     void GetPurgTotal(const ValueMap &meminfo, StringMatrix result);
145     void GetPurgByPid(const int32_t &pid, StringMatrix result);
146     void GetDmaByPid(MemInfoData::GraphicsMemory& graphicsMemory, StringMatrix result);
147     void GetHiaiServerIon(const int32_t &pid, StringMatrix result);
148     void GetNativeHeap(const GroupMap& nativeGroupMap, StringMatrix result);
149     void GetNativeValue(const std::string& tag, const GroupMap& nativeGroupMap, StringMatrix result);
150     void GetRamCategory(const GroupMap &smapsinfos, const ValueMap &meminfos, StringMatrix result);
151     void SetGraphGroupMap(GroupMap& groupMap, MemInfoData::GraphicsMemory &graphicsMemory);
152     void AddBlankLine(StringMatrix result);
153     void MemUsageToMatrix(const MemInfoData::MemUsage &memUsage, StringMatrix result);
154     void PairToStringMatrix(const std::string &titleStr, std::vector<std::pair<std::string, uint64_t>> &vec,
155                             StringMatrix result);
156     void AddMemByProcessTitle(StringMatrix result, std::string sortType);
157 
158     static uint64_t GetVss(const int32_t &pid);
159     static std::string GetProcName(const int32_t &pid);
160     static uint64_t GetProcValue(const int32_t &pid, const std::string& key);
161     static std::string GetProcessAdjLabel(const int32_t pid);
162     static std::string GetReclaimPriorityString(int32_t priority);
163     static void InitMemInfo(MemInfoData::MemInfo &memInfo);
164     static void InitMemUsage(MemInfoData::MemUsage &usage);
165     void CalcGroup(const GroupMap &infos, StringMatrix result);
166     void GetSortedMemoryInfoNoPid(StringMatrix result);
167     bool GetGraphicsMemory(int32_t pid, MemInfoData::GraphicsMemory& graphicsMemory, GraphicType graphicType);
168     void GetMemoryByAdj(StringMatrix result);
169     void SetPss(MemInfoData::MemInfo &meminfo, uint64_t value);
170     void SetSharedClean(MemInfoData::MemInfo &meminfo, uint64_t value);
171     void SetSharedDirty(MemInfoData::MemInfo &meminfo, uint64_t value);
172     void SetPrivateClean(MemInfoData::MemInfo &meminfo, uint64_t value);
173     void SetPrivateDirty(MemInfoData::MemInfo &meminfo, uint64_t value);
174     void SetSwap(MemInfoData::MemInfo &meminfo, uint64_t value);
175     void SetSwapPss(MemInfoData::MemInfo &meminfo, uint64_t value);
176     void SetHeapSize(MemInfoData::MemInfo &meminfo, uint64_t value);
177     void SetHeapAlloc(MemInfoData::MemInfo &meminfo, uint64_t value);
178     void SetHeapFree(MemInfoData::MemInfo &meminfo, uint64_t value);
179 };
180 } // namespace HiviewDFX
181 } // namespace OHOS
182 #endif
183