[libcxx-commits] [PATCH] D113066: [libcxx][SystemZ][z/OS] Update libcxx/src/memory.cpp to accommodate POSIX(OFF)

Daniel McIntosh via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Tue Nov 2 15:46:12 PDT 2021


DanielMcIntosh-IBM created this revision.
DanielMcIntosh-IBM added reviewers: jroelofs, bcraig, EricWF, Quuxplusone, ldionne.
DanielMcIntosh-IBM requested review of this revision.
Herald added a project: libc++.
Herald added a subscriber: libcxx-commits.
Herald added a reviewer: libc++.

Add an early return from `__sp_mut::lock()` and unlock when we're in a
single-threaded environment to prevent the shared_ptr std::atomic_... overloads
from calling mutex functions when the threading API is disabled.

Depends on D110349 <https://reviews.llvm.org/D110349>


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D113066

Files:
  libcxx/src/memory.cpp


Index: libcxx/src/memory.cpp
===================================================================
--- libcxx/src/memory.cpp
+++ libcxx/src/memory.cpp
@@ -149,23 +149,37 @@
 void
 __sp_mut::lock() noexcept
 {
-    auto m = static_cast<__libcpp_mutex_t*>(__lx);
-    unsigned count = 0;
-    while (!__libcpp_mutex_trylock(m))
-    {
-        if (++count > 16)
-        {
-            __libcpp_mutex_lock(m);
-            break;
-        }
-        this_thread::yield();
+  // The __sp_mut class should only be used for the shared_ptr overloads of
+  // std::atomic_... functions. Ownership of __sp_mut is always released
+  // before the end of any of these overloads, and none of them spawn new
+  // threads. Thus, there is no danger of one thread calling __sp_mut::lock
+  // and skipping acquisition of __lx followed by another thread calling it
+  // (and acquiring __lx) before the first thread calls __sp_mut::unlock.
+  //
+  // We can't acquire the mutex when the threading API is disabled. Since we
+  // don't need to acquire it when single-threaded anyways, we just don't
+  // bother aquiring the mutex unless we're multi-threaded (and thus the
+  // threading API is enabled).
+  if (!__libcpp_has_spawned_other_threads())
+    return;
+  auto m = static_cast<__libcpp_mutex_t*>(__lx);
+  unsigned count = 0;
+  while (!__libcpp_mutex_trylock(m)) {
+    if (++count > 16) {
+      __libcpp_mutex_lock(m);
+      break;
     }
+    this_thread::yield();
+  }
 }
 
 void
 __sp_mut::unlock() noexcept
 {
-    __libcpp_mutex_unlock(static_cast<__libcpp_mutex_t*>(__lx));
+  // See comment in __sp_mut::lock() for discussion of why this is safe.
+  if (!__libcpp_has_spawned_other_threads())
+    return;
+  __libcpp_mutex_unlock(static_cast<__libcpp_mutex_t*>(__lx));
 }
 
 __sp_mut&


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D113066.384260.patch
Type: text/x-patch
Size: 1792 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20211102/661fb107/attachment.bin>


More information about the libcxx-commits mailing list