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 #ifndef OHOS_MEMORY_MEMMGR_MEMORY_PRESSURE_MONITOR_H
17 #define OHOS_MEMORY_MEMMGR_MEMORY_PRESSURE_MONITOR_H
18 
19 #include "event_handler.h"
20 
21 struct epoll_event;
22 
23 #define MS_PER_SECOND 1000
24 
25 #define NS_PER_MS 1000000
26 
27 #define US_PER_MS 1000
28 
29 #define WINDOW_IN_MS 1000
30 
31 #define MEMORY_PRESSURE_FILE "/proc/pressure/memory"
32 
33 #define POLL_PERIOD_MS 10
34 
35 #define POLL_COUNT (WINDOW_IN_MS / POLL_PERIOD_MS)
36 
37 namespace OHOS {
38 namespace Memory {
39 enum MemPressureLevel {
40     LEVEL_0 = 0,
41     MEM_PRESS_LEVEL_COUNT
42 };
43 
44 enum StallType {
45     SOME,
46     FULL,
47     STALL_TYPE_COUNT
48 };
49 
50 struct LevelHandler {
51     int data;
52     void (*handler)(int data, uint32_t events);
53 };
54 
55 struct MemPressLevelCfg {
56     enum MemPressureLevel level;
57     enum StallType stallType;
58     int thresholdInMs;
59     int levelFileFd;
60     struct LevelHandler levelHandler;
61 };
62 
63 static struct MemPressLevelCfg levelConfigArr[MEM_PRESS_LEVEL_COUNT] = {
64     { LEVEL_0, SOME, 10, -1},    /* 10ms out of 1sec for partial stall */
65 };
66 
67 
68 void HandleLevelReport(int level, uint32_t events);
69 
70 class MemoryPressureObserver {
71 public:
72     MemoryPressureObserver();
73     ~MemoryPressureObserver();
74     void Init();
75 private:
76     // run MainLoop on handler thread
77     std::shared_ptr<AppExecFwk::EventHandler> handler_;
78     int epollfd_ = -1;
79     // current monitor level count
80     int curLevelCount_ = 0;
81     struct LevelHandler *handlerInfo_ = nullptr;
82 
83     bool MonitorLevel(MemPressureLevel level);
84     int CreateLevelFileFd(StallType stallType, int thresholdInUs, int windowInUs);
85     int AddLevelFileFdToEpoll(int epollfd, int fd, void* data);
86     void UnMonitorLevel(MemPressureLevel level);
87     int delLevelFileFdFromEpoll(int epollfd, int fd);
88     void CloseLevelFileFd(int fd);
89     void MainLoop(void);
90     void HandleEpollEvent(struct epoll_event *curEpollEvent);
91 };
92 } // namespace Memory
93 } // namespace OHOS
94 #endif // OHOS_MEMORY_MEMMGR_MEMORY_PRESSURE_MONITOR_H
95