static int g_psi_monitor_epoll_fd = -1;
static pthread_t g_psi_monitor_thread;
static int g_psi_monitor_thread_destroy_event_fd = -1;
+static enum psi_mem_level g_current_psi_mem_level = PSI_MEM_LEVEL_UNKNOWN;
static void assert_psi_mem_level(int psi_mem_level)
{
static void *psi_memory_monitor_handler(struct psi_memory_monitor_info *info)
{
- static unsigned int prev_available_mb;
- unsigned int available_mb;
- int mem_level;
-
assert_psi_mem_level(info->psi_mem_level);
- available_mb = proc_get_mem_available();
- if (prev_available_mb == available_mb)
- return NULL;
-
- mem_level = lowmem_check_mem_state(available_mb);
- lowmem_trigger_memory_state_action(mem_level);
- prev_available_mb = available_mb;
+ if (g_current_psi_mem_level < info->psi_mem_level)
+ g_current_psi_mem_level = info->psi_mem_level;
return NULL;
}
info->fd = -1;
}
+static void raise_lowmem_event(void)
+{
+ static unsigned int prev_available_mb;
+ unsigned int available_mb;
+ int mem_level;
+
+ switch (g_current_psi_mem_level) {
+ case PSI_MEM_LEVEL_LOW:
+ case PSI_MEM_LEVEL_MEDIUM:
+ case PSI_MEM_LEVEL_HIGH:
+ break;
+ default:
+ return;
+ }
+
+ available_mb = proc_get_mem_available();
+ if (prev_available_mb == available_mb)
+ return;
+
+ mem_level = lowmem_check_mem_state(available_mb);
+ lowmem_trigger_memory_state_action(mem_level);
+ prev_available_mb = available_mb;
+}
+
static void *psi_monitor_thread_worker(void *data)
{
struct epoll_event events[EPOLL_LISTENER_MAX_EVENTS];
while (1) {
events_num = epoll_wait(g_psi_monitor_epoll_fd, events, EPOLL_LISTENER_MAX_EVENTS, -1);
+ g_current_psi_mem_level = PSI_MEM_LEVEL_UNKNOWN;
for (int i = 0; i < events_num; ++i) {
if (events[i].events & (EPOLLERR | EPOLLHUP))
continue;
struct epoll_event_data *event_data = events[i].data.ptr;
event_data->handler(event_data->data);
}
+
+ raise_lowmem_event();
}
pthread_exit(NULL);