[Lldb-commits] [lldb] [lldb] Use llvm::sys::RWMutex instead of std::shared_mutex (NFC) (PR #197847)

Jonas Devlieghere via lldb-commits lldb-commits at lists.llvm.org
Thu May 14 17:08:10 PDT 2026


https://github.com/JDevlieghere created https://github.com/llvm/llvm-project/pull/197847

On Darwin, pthread_rwlock is faster than std::shared_mutex, which is why the implementation of llvm::sys::RWMutex used that on our platform. Everywhere else, it uses std::shared_mutex under the hood.

Also see #70151

>From 31ca39cfbaa116223736ee20aec7f650fcdb262d Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere <jonas at devlieghere.com>
Date: Thu, 14 May 2026 17:05:43 -0700
Subject: [PATCH] [lldb] Use llvm::sys::RWMutex instead of std::shared_mutex
 (NFC)

On Darwin, pthread_rwlock is faster than std::shared_mutex, which is why
the implementation of llvm::sys::RWMutex used that on our platform.
Everywhere else, it uses std::shared_mutex under the hood.

Also see #70151
---
 lldb/include/lldb/Target/StackFrameList.h |  9 ++++-----
 lldb/source/Target/StackFrameList.cpp     | 22 +++++++++++-----------
 2 files changed, 15 insertions(+), 16 deletions(-)

diff --git a/lldb/include/lldb/Target/StackFrameList.h b/lldb/include/lldb/Target/StackFrameList.h
index 6e69ff546814e..e979fd9be44f2 100644
--- a/lldb/include/lldb/Target/StackFrameList.h
+++ b/lldb/include/lldb/Target/StackFrameList.h
@@ -11,10 +11,10 @@
 
 #include <memory>
 #include <mutex>
-#include <shared_mutex>
 #include <vector>
 
 #include "lldb/Target/StackFrame.h"
+#include "llvm/Support/RWMutex.h"
 
 namespace lldb_private {
 
@@ -187,7 +187,7 @@ class StackFrameList : public std::enable_shared_from_this<StackFrameList> {
   /// unique lock is Clear.  All other clients take the shared lock, though
   /// if we need more frames we may swap shared for unique to fulfill that
   /// requirement.
-  mutable std::shared_mutex m_list_mutex;
+  mutable llvm::sys::RWMutex m_list_mutex;
 
   // Setting the inlined depth should be protected against other attempts to
   // change it, but since it doesn't mutate the list itself, we can limit the
@@ -243,9 +243,8 @@ class StackFrameList : public std::enable_shared_from_this<StackFrameList> {
 
 private:
   uint32_t SetSelectedFrameNoLock(lldb_private::StackFrame *frame);
-  lldb::StackFrameSP
-  GetFrameAtIndexNoLock(uint32_t idx,
-                        std::shared_lock<std::shared_mutex> &guard);
+  lldb::StackFrameSP GetFrameAtIndexNoLock(uint32_t idx,
+                                           llvm::sys::ScopedReader &guard);
 
   /// @{
   /// These two Fetch frames APIs and SynthesizeTailCallFrames are called in
diff --git a/lldb/source/Target/StackFrameList.cpp b/lldb/source/Target/StackFrameList.cpp
index 97b54403bec8b..ede858e2faae8 100644
--- a/lldb/source/Target/StackFrameList.cpp
+++ b/lldb/source/Target/StackFrameList.cpp
@@ -204,7 +204,7 @@ void StackFrameList::SetCurrentInlinedDepth(uint32_t new_depth) {
 }
 
 bool StackFrameList::WereAllFramesFetched() const {
-  std::shared_lock<std::shared_mutex> guard(m_list_mutex);
+  llvm::sys::ScopedReader guard(m_list_mutex);
   return GetAllFramesFetched();
 }
 
@@ -446,7 +446,7 @@ bool StackFrameList::GetFramesUpTo(uint32_t end_idx,
                                    InterruptionControl allow_interrupt) {
   // GetFramesUpTo is always called with the intent to add frames, so get the
   // writer lock:
-  std::unique_lock<std::shared_mutex> guard(m_list_mutex);
+  llvm::sys::ScopedWriter guard(m_list_mutex);
   // Now that we have the lock, check to make sure someone didn't get there
   // ahead of us:
   if (m_frames.size() > end_idx || GetAllFramesFetched())
@@ -663,7 +663,7 @@ uint32_t StackFrameList::GetNumFrames(bool can_create) {
   }
   uint32_t frame_idx;
   {
-    std::shared_lock<std::shared_mutex> guard(m_list_mutex);
+    llvm::sys::ScopedReader guard(m_list_mutex);
     frame_idx = GetVisibleStackFrameIndex(m_frames.size());
   }
   return frame_idx;
@@ -673,7 +673,7 @@ void StackFrameList::Dump(Stream *s) {
   if (s == nullptr)
     return;
 
-  std::shared_lock<std::shared_mutex> guard(m_list_mutex);
+  llvm::sys::ScopedReader guard(m_list_mutex);
 
   const_iterator pos, begin = m_frames.begin(), end = m_frames.end();
   for (pos = begin; pos != end; ++pos) {
@@ -697,7 +697,7 @@ StackFrameSP StackFrameList::GetFrameAtIndex(uint32_t idx) {
   // enough frames for our request we don't want to block other readers, so
   // first acquire the shared lock:
   { // Scope for shared lock:
-    std::shared_lock<std::shared_mutex> guard(m_list_mutex);
+    llvm::sys::ScopedReader guard(m_list_mutex);
 
     uint32_t inlined_depth = GetCurrentInlinedDepth();
     if (inlined_depth != UINT32_MAX)
@@ -720,7 +720,7 @@ StackFrameSP StackFrameList::GetFrameAtIndex(uint32_t idx) {
   }
 
   { // Now we're accessing m_frames as a reader, so acquire the reader lock.
-    std::shared_lock<std::shared_mutex> guard(m_list_mutex);
+    llvm::sys::ScopedReader guard(m_list_mutex);
     if (idx < m_frames.size()) {
       frame_sp = m_frames[idx];
     } else if (original_idx == 0) {
@@ -773,7 +773,7 @@ StackFrameSP StackFrameList::GetFrameWithStackID(const StackID &stack_id) {
     {
       // First see if the frame is already realized.  This is the scope for
       // the shared mutex:
-      std::shared_lock<std::shared_mutex> guard(m_list_mutex);
+      llvm::sys::ScopedReader guard(m_list_mutex);
       // Do a binary search in case the stack frame is already in our cache
       collection::const_iterator pos =
           llvm::lower_bound(m_frames, stack_id, CompareStackID);
@@ -792,7 +792,7 @@ StackFrameSP StackFrameList::GetFrameWithStackID(const StackID &stack_id) {
 }
 
 bool StackFrameList::SetFrameAtIndex(uint32_t idx, StackFrameSP &frame_sp) {
-  std::unique_lock<std::shared_mutex> guard(m_list_mutex);
+  llvm::sys::ScopedWriter guard(m_list_mutex);
   if (idx >= m_frames.size())
     m_frames.resize(idx + 1);
   // Make sure allocation succeeded by checking bounds again
@@ -887,7 +887,7 @@ StackFrameList::GetSelectedFrameIndex(SelectMostRelevant select_most_relevant) {
 }
 
 uint32_t StackFrameList::SetSelectedFrame(lldb_private::StackFrame *frame) {
-  std::shared_lock<std::shared_mutex> guard(m_list_mutex);
+  llvm::sys::ScopedReader guard(m_list_mutex);
   std::lock_guard<std::recursive_mutex> selected_frame_guard(
       m_selected_frame_mutex);
 
@@ -940,7 +940,7 @@ void StackFrameList::SetDefaultFileAndLineToSelectedFrame() {
 // does not describe how StackFrameLists are currently used.
 // Clear is currently only used to clear the list in the destructor.
 void StackFrameList::Clear() {
-  std::unique_lock<std::shared_mutex> guard(m_list_mutex);
+  llvm::sys::ScopedWriter guard(m_list_mutex);
   m_frames.clear();
   m_concrete_frames_fetched = 0;
   std::lock_guard<std::recursive_mutex> selected_frame_guard(
@@ -950,7 +950,7 @@ void StackFrameList::Clear() {
 
 lldb::StackFrameSP
 StackFrameList::GetStackFrameSPForStackFramePtr(StackFrame *stack_frame_ptr) {
-  std::shared_lock<std::shared_mutex> guard(m_list_mutex);
+  llvm::sys::ScopedReader guard(m_list_mutex);
   const_iterator pos;
   const_iterator begin = m_frames.begin();
   const_iterator end = m_frames.end();



More information about the lldb-commits mailing list