bool MemoryPressureHandler::tryEnsureEventFD() { // If the env var to use the poll method based on meminfo is set, this method overrides anything else. if (m_eventFD != -1 && defaultPollMaximumProcessMemory(s_pollMaximumProcessMemoryCriticalLimit, s_pollMaximumProcessMemoryNonCriticalLimit)) { m_eventFD = -1; return true; } if (m_eventFD) return true; auto setupCgroups = [this]() -> bool { int fd = eventfd(0, EFD_CLOEXEC); if (fd == -1) { LOG(MemoryPressure, "eventfd() failed: %m"); return false; } m_eventFD = fd; fd = open(s_cgroupMemoryPressureLevel, O_CLOEXEC | O_RDONLY); if (fd == -1) { logErrorAndCloseFDs("Failed to open memory.pressure_level"); return false; } m_pressureLevelFD = fd; fd = open(s_cgroupEventControl, O_CLOEXEC | O_WRONLY); if (fd == -1) { logErrorAndCloseFDs("Failed to open cgroup.event_control"); return false; } char line[128] = {0, }; if (snprintf(line, sizeof(line), "%d %d low", m_eventFD.value(), m_pressureLevelFD.value()) < 0 || write(fd, line, strlen(line) + 1) < 0) { logErrorAndCloseFDs("Failed to write cgroup.event_control"); close(fd); return false; } return true; }; if (setupCgroups()) return true; return false; }
void MemoryPressureHandler::install() { if (m_installed) return; m_eventFD = eventfd(0, EFD_CLOEXEC); if (m_eventFD == -1) { LOG(MemoryPressure, "eventfd() failed: %m"); return; } m_pressureLevelFD = open(s_cgroupMemoryPressureLevel, O_CLOEXEC | O_RDONLY); if (m_pressureLevelFD == -1) { logErrorAndCloseFDs("Failed to open memory.pressure_level"); return; } int fd = open(s_cgroupEventControl, O_CLOEXEC | O_WRONLY); if (fd == -1) { logErrorAndCloseFDs("Failed to open cgroup.event_control"); return; } char line[128] = {0, }; if (snprintf(line, sizeof(line), "%d %d low", m_eventFD, m_pressureLevelFD) < 0 || write(fd, line, strlen(line) + 1) < 0) { logErrorAndCloseFDs("Failed to write cgroup.event_control"); close(fd); return; } close(fd); m_threadID = createThread(waitForMemoryPressureEvent, this, "WebCore: MemoryPressureHandler"); if (!m_threadID) { logErrorAndCloseFDs("Failed to create a thread for MemoryPressureHandler"); return; } if (ReliefLogger::loggingEnabled() && isUnderMemoryPressure()) LOG(MemoryPressure, "System is no longer under memory pressure."); setUnderMemoryPressure(false); m_installed = true; }
void MemoryPressureHandler::uninstall() { if (!m_installed) return; if (m_threadID) { detachThread(m_threadID); m_threadID = 0; } logErrorAndCloseFDs(nullptr); m_installed = false; }