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

Reply via email to