llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-lldb Author: None (llvmbot) <details> <summary>Changes</summary> Backport a5ffce0faebe5f49d8befb774f4cb781b9e33df7 Requested by: @<!-- -->da-viper --- Full diff: https://github.com/llvm/llvm-project/pull/179199.diff 2 Files Affected: - (modified) lldb/include/lldb/Host/MemoryMonitor.h (+2-1) - (modified) lldb/source/Host/common/MemoryMonitor.cpp (+90-19) ``````````diff diff --git a/lldb/include/lldb/Host/MemoryMonitor.h b/lldb/include/lldb/Host/MemoryMonitor.h index 504f5f9cba96b..541a647c2276f 100644 --- a/lldb/include/lldb/Host/MemoryMonitor.h +++ b/lldb/include/lldb/Host/MemoryMonitor.h @@ -11,6 +11,7 @@ #include <functional> #include <memory> +#include <utility> namespace lldb_private { @@ -18,7 +19,7 @@ class MemoryMonitor { public: using Callback = std::function<void()>; - MemoryMonitor(Callback callback) : m_callback(callback) {} + MemoryMonitor(Callback callback) : m_callback(std::move(callback)) {} virtual ~MemoryMonitor() = default; /// MemoryMonitor is not copyable. diff --git a/lldb/source/Host/common/MemoryMonitor.cpp b/lldb/source/Host/common/MemoryMonitor.cpp index dbd44a4774758..7734be8688675 100644 --- a/lldb/source/Host/common/MemoryMonitor.cpp +++ b/lldb/source/Host/common/MemoryMonitor.cpp @@ -13,7 +13,6 @@ #include "lldb/Utility/Log.h" #include "llvm/ADT/ScopeExit.h" #include "llvm/Support/Error.h" -#include <atomic> #include <cstddef> #include <cstdio> #include <cstring> @@ -21,46 +20,113 @@ #if defined(__linux__) #include <fcntl.h> #include <poll.h> +#include <sys/eventfd.h> +#include <sys/poll.h> #include <unistd.h> #endif #if defined(_WIN32) +#include <atomic> #include <windows.h> #endif using namespace lldb_private; -class MemoryMonitorPoll : public MemoryMonitor { +#if defined(__linux__) +class MemoryMonitorLinux : public MemoryMonitor { public: using MemoryMonitor::MemoryMonitor; + explicit MemoryMonitorLinux(Callback callback) + : MemoryMonitor(std::move(callback)), + m_stop_fd(::eventfd(0, EFD_NONBLOCK)) {} + + ~MemoryMonitorLinux() { + if (m_memory_monitor_thread.IsJoinable()) + m_memory_monitor_thread.Join(nullptr); + if (m_stop_fd != 1) + ::close(m_stop_fd); + } + + void Start() override { + if (m_stop_fd < 0) { + LLDB_LOG_ERROR( + GetLog(LLDBLog::Host), + llvm::errorCodeToError(llvm::errnoAsErrorCode()), + "failed to create stop file descriptor for memory monitor: {0}"); + return; + } + + llvm::Expected<HostThread> memory_monitor_thread = + ThreadLauncher::LaunchThread("memory.monitor", + [this] { return MonitorThread(); }); + if (memory_monitor_thread) { + m_memory_monitor_thread = *memory_monitor_thread; + } else { + LLDB_LOG_ERROR(GetLog(LLDBLog::Host), memory_monitor_thread.takeError(), + "failed to launch host thread: {0}"); + } + } + + void Stop() override { + if (m_memory_monitor_thread.IsJoinable()) { + if (m_stop_fd != -1) + ::eventfd_write(m_stop_fd, 1); + m_memory_monitor_thread.Join(nullptr); + } + } + +private: lldb::thread_result_t MonitorThread() { -#if defined(__linux__) - struct pollfd fds; - fds.fd = open("/proc/pressure/memory", O_RDWR | O_NONBLOCK); - if (fds.fd < 0) + constexpr size_t pressure_idx = 0; + constexpr size_t stop_idx = 1; + constexpr size_t fd_count = 2; + std::array<pollfd, fd_count> pfds{}; + + // Setup stop file descriptor. + pfds[stop_idx].fd = m_stop_fd; + pfds[stop_idx].events = POLLIN; + + // Setup pressure file descriptor. + pfds[pressure_idx].fd = + ::open("/proc/pressure/memory", O_RDWR | O_NONBLOCK); + if (pfds[pressure_idx].fd < 0) return {}; - fds.events = POLLPRI; + pfds[pressure_idx].events = POLLPRI; - llvm::scope_exit cleanup([&]() { close(fds.fd); }); + llvm::scope_exit cleanup([&]() { ::close(pfds[pressure_idx].fd); }); // Detect a 50ms stall in a 2 second time window. - const char trig[] = "some 50000 2000000"; - if (write(fds.fd, trig, strlen(trig) + 1) < 0) + constexpr llvm::StringRef trigger = "some 50000 2000000"; + if (::write(pfds[pressure_idx].fd, trigger.data(), trigger.size() + 1) < 0) return {}; - while (!m_done) { - int n = poll(&fds, 1, g_timeout); + while (true) { + constexpr int timeout_infinite = -1; + const int n = ::poll(pfds.data(), pfds.size(), timeout_infinite); if (n > 0) { - if (fds.revents & POLLERR) + // Handle stop event. + if (pfds[stop_idx].revents & (POLLIN | POLLERR)) return {}; - if (fds.revents & POLLPRI) + + if (pfds[pressure_idx].revents & POLLERR) + return {}; + if (pfds[pressure_idx].revents & POLLPRI) m_callback(); } } -#endif + return {}; + } + int m_stop_fd = -1; + HostThread m_memory_monitor_thread; +}; +#elif defined(_WIN32) -#if defined(_WIN32) +class MemoryMonitorWindows : public MemoryMonitor { +public: + using MemoryMonitor::MemoryMonitor; + + lldb::thread_result_t MonitorThread() { HANDLE low_memory_notification = CreateMemoryResourceNotification(LowMemoryResourceNotification); if (!low_memory_notification) @@ -72,8 +138,6 @@ class MemoryMonitorPoll : public MemoryMonitor { m_callback(); } } -#endif - return {}; } @@ -101,9 +165,16 @@ class MemoryMonitorPoll : public MemoryMonitor { std::atomic<bool> m_done = false; HostThread m_memory_monitor_thread; }; +#endif #if !defined(__APPLE__) std::unique_ptr<MemoryMonitor> MemoryMonitor::Create(Callback callback) { - return std::make_unique<MemoryMonitorPoll>(callback); +#if defined(__linux__) + return std::make_unique<MemoryMonitorLinux>(std::move(callback)); +#elif defined(_WIN32) + return std::make_unique<MemoryMonitorWindows>(std::move(callback)); +#else + return nullptr; +#endif } #endif `````````` </details> https://github.com/llvm/llvm-project/pull/179199 _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
