[libcxx-commits] [libcxx] [libc++] Make `std::lock_guard` available with `_LIBCPP_HAS_NO_THREADS` (PR #98717)

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Tue Jul 16 12:51:31 PDT 2024


https://github.com/ldionne updated https://github.com/llvm/llvm-project/pull/98717

>From 1aec8cd07c1b0f6f45cf54e640d8265299ee86c4 Mon Sep 17 00:00:00 2001
From: Petr Hosek <phosek at google.com>
Date: Fri, 12 Jul 2024 22:50:34 -0700
Subject: [PATCH 01/15] [libcxx] Make locks available with
 _LIBCPP_HAS_NO_THREADS

This change makes std::lock_guard, std::unique_lock, std::scoped_lock,
and std::shared_lock available when _LIBCPP_HAS_NO_THREADS is set.
These classes are generic and don't require threading support, and are
regularly used even in environments where threading isn't available like
embedded.

fixes #89891
---
 libcxx/include/__mutex/lock_guard.h  |  4 ----
 libcxx/include/__mutex/unique_lock.h |  4 ----
 libcxx/include/mutex                 |  6 +++---
 libcxx/include/shared_mutex          | 15 +++++++--------
 4 files changed, 10 insertions(+), 19 deletions(-)

diff --git a/libcxx/include/__mutex/lock_guard.h b/libcxx/include/__mutex/lock_guard.h
index 8340b9bbd4453..ef56896be9f68 100644
--- a/libcxx/include/__mutex/lock_guard.h
+++ b/libcxx/include/__mutex/lock_guard.h
@@ -16,8 +16,6 @@
 #  pragma GCC system_header
 #endif
 
-#ifndef _LIBCPP_HAS_NO_THREADS
-
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Mutex>
@@ -47,6 +45,4 @@ _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(lock_guard);
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_HAS_NO_THREADS
-
 #endif // _LIBCPP___MUTEX_LOCK_GUARD_H
diff --git a/libcxx/include/__mutex/unique_lock.h b/libcxx/include/__mutex/unique_lock.h
index 4a616ba51ee1c..5df791de4c742 100644
--- a/libcxx/include/__mutex/unique_lock.h
+++ b/libcxx/include/__mutex/unique_lock.h
@@ -22,8 +22,6 @@
 #  pragma GCC system_header
 #endif
 
-#ifndef _LIBCPP_HAS_NO_THREADS
-
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Mutex>
@@ -172,6 +170,4 @@ inline _LIBCPP_HIDE_FROM_ABI void swap(unique_lock<_Mutex>& __x, unique_lock<_Mu
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_HAS_NO_THREADS
-
 #endif // _LIBCPP___MUTEX_UNIQUE_LOCK_H
diff --git a/libcxx/include/mutex b/libcxx/include/mutex
index 02c52dd72f02b..d4d7539240094 100644
--- a/libcxx/include/mutex
+++ b/libcxx/include/mutex
@@ -419,8 +419,9 @@ inline _LIBCPP_HIDE_FROM_ABI void lock(_L0& __l0, _L1& __l1, _L2& __l2, _L3&...
 }
 
 #  endif // _LIBCPP_CXX03_LANG
+#endif   // !_LIBCPP_HAS_NO_THREADS
 
-#  if _LIBCPP_STD_VER >= 17
+#if _LIBCPP_STD_VER >= 17
 template <class... _Mutexes>
 class _LIBCPP_TEMPLATE_VIS scoped_lock;
 
@@ -491,8 +492,7 @@ private:
 };
 _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(scoped_lock);
 
-#  endif // _LIBCPP_STD_VER >= 17
-#endif   // !_LIBCPP_HAS_NO_THREADS
+#endif // _LIBCPP_STD_VER >= 17
 
 _LIBCPP_END_NAMESPACE_STD
 
diff --git a/libcxx/include/shared_mutex b/libcxx/include/shared_mutex
index 397ac290d9b2e..5918af4a214c1 100644
--- a/libcxx/include/shared_mutex
+++ b/libcxx/include/shared_mutex
@@ -122,16 +122,11 @@ template <class Mutex>
 
 */
 
-#include <__config>
-
-#ifdef _LIBCPP_HAS_NO_THREADS
-#  error "<shared_mutex> is not supported since libc++ has been configured without support for threads."
-#endif
-
 #include <__chrono/duration.h>
 #include <__chrono/steady_clock.h>
 #include <__chrono/time_point.h>
 #include <__condition_variable/condition_variable.h>
+#include <__config>
 #include <__memory/addressof.h>
 #include <__mutex/mutex.h>
 #include <__mutex/tag_types.h>
@@ -152,6 +147,8 @@ _LIBCPP_PUSH_MACROS
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
+#  ifndef _LIBCPP_HAS_NO_THREADS
+
 struct _LIBCPP_EXPORTED_FROM_ABI __shared_mutex_base {
   mutex __mut_;
   condition_variable __gate1_;
@@ -181,7 +178,7 @@ struct _LIBCPP_EXPORTED_FROM_ABI __shared_mutex_base {
   //     native_handle_type native_handle(); // See 30.2.3
 };
 
-#  if _LIBCPP_STD_VER >= 17
+#    if _LIBCPP_STD_VER >= 17
 class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_THREAD_SAFETY_ANNOTATION(__capability__("shared_mutex")) shared_mutex {
   __shared_mutex_base __base_;
 
@@ -218,7 +215,7 @@ public:
   //     typedef __shared_mutex_base::native_handle_type native_handle_type;
   //     _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return __base::unlock_shared(); }
 };
-#  endif
+#    endif
 
 class _LIBCPP_EXPORTED_FROM_ABI
 _LIBCPP_THREAD_SAFETY_ANNOTATION(__capability__("shared_timed_mutex")) shared_timed_mutex {
@@ -308,6 +305,8 @@ bool shared_timed_mutex::try_lock_shared_until(const chrono::time_point<_Clock,
   return true;
 }
 
+#  endif   // !_LIBCPP_HAS_NO_THREADS
+
 template <class _Mutex>
 class shared_lock {
 public:

>From 2b4d4305582570620a27a6c7c30a4053da63143c Mon Sep 17 00:00:00 2001
From: Petr Hosek <phosek at google.com>
Date: Sat, 13 Jul 2024 16:28:26 -0700
Subject: [PATCH 02/15] Update test annotations

---
 .../thread.lock/thread.lock.guard/assign.compile.fail.cpp      | 2 ++
 .../thread.lock/thread.lock.guard/copy.compile.fail.cpp        | 2 ++
 .../thread.lock/thread.lock.scoped/adopt_lock.pass.cpp         | 3 +--
 .../thread.mutex/thread.lock/thread.lock.scoped/mutex.pass.cpp | 3 +--
 .../thread.lock.shared.locking/try_lock_for.pass.cpp           | 3 +--
 .../thread.lock.shared.locking/try_lock_until.pass.cpp         | 3 +--
 .../thread.lock.shared.locking/unlock.pass.cpp                 | 3 +--
 .../thread.lock.shared.mod/member_swap.pass.cpp                | 3 +--
 .../thread.lock.shared.mod/nonmember_swap.pass.cpp             | 3 +--
 .../thread.lock.shared/thread.lock.shared.mod/release.pass.cpp | 3 +--
 .../thread.lock.shared/thread.lock.shared.obs/op_bool.pass.cpp | 3 +--
 .../thread.lock.unique.locking/try_lock.pass.cpp               | 3 +--
 .../thread.lock.unique.locking/try_lock_for.pass.cpp           | 3 +--
 .../thread.lock.unique.locking/try_lock_until.pass.cpp         | 3 +--
 .../thread.lock.unique.mod/member_swap.pass.cpp                | 2 --
 .../thread.lock.unique.mod/nonmember_swap.pass.cpp             | 2 --
 .../thread.lock.unique/thread.lock.unique.mod/release.pass.cpp | 2 --
 17 files changed, 16 insertions(+), 30 deletions(-)

diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/assign.compile.fail.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/assign.compile.fail.cpp
index 2d0f438ed0391..330cae19d1fea 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/assign.compile.fail.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/assign.compile.fail.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: no-threads
+
 // <mutex>
 
 // template <class Mutex> class lock_guard;
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/copy.compile.fail.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/copy.compile.fail.cpp
index e99517e47e8c6..7e9dd43a6bb32 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/copy.compile.fail.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/copy.compile.fail.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: no-threads
+
 // <mutex>
 
 // template <class Mutex> class lock_guard;
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.scoped/adopt_lock.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.scoped/adopt_lock.pass.cpp
index 83b29ff669dca..a48caf7fdbb51 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.scoped/adopt_lock.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.scoped/adopt_lock.pass.cpp
@@ -5,8 +5,7 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
-//
-// UNSUPPORTED: no-threads
+
 // UNSUPPORTED: c++03, c++11, c++14
 
 // <mutex>
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.scoped/mutex.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.scoped/mutex.pass.cpp
index f953fa4f8d6df..0812c33c22226 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.scoped/mutex.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.scoped/mutex.pass.cpp
@@ -5,8 +5,7 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
-//
-// UNSUPPORTED: no-threads
+
 // UNSUPPORTED: c++03, c++11, c++14
 
 // <mutex>
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_for.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_for.pass.cpp
index d28ae395ccb0d..3b3c34f0b9351 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_for.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_for.pass.cpp
@@ -5,8 +5,7 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
-//
-// UNSUPPORTED: no-threads
+
 // UNSUPPORTED: c++03, c++11
 
 // <shared_mutex>
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_until.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_until.pass.cpp
index 880bf1cbd4999..ab5f3c7b6a935 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_until.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_until.pass.cpp
@@ -5,8 +5,7 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
-//
-// UNSUPPORTED: no-threads
+
 // UNSUPPORTED: c++03, c++11
 
 // <shared_mutex>
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/unlock.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/unlock.pass.cpp
index 4f31a75f68dec..0fcab6d346699 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/unlock.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/unlock.pass.cpp
@@ -5,8 +5,7 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
-//
-// UNSUPPORTED: no-threads
+
 // UNSUPPORTED: c++03, c++11
 
 // <shared_mutex>
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/member_swap.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/member_swap.pass.cpp
index aeca2022ba9c9..af904434efd82 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/member_swap.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/member_swap.pass.cpp
@@ -5,8 +5,7 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
-//
-// UNSUPPORTED: no-threads
+
 // UNSUPPORTED: c++03, c++11
 
 // <shared_mutex>
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/nonmember_swap.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/nonmember_swap.pass.cpp
index 25e5cf624caa8..a2827b0292e76 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/nonmember_swap.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/nonmember_swap.pass.cpp
@@ -5,8 +5,7 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
-//
-// UNSUPPORTED: no-threads
+
 // UNSUPPORTED: c++03, c++11
 
 // <shared_mutex>
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/release.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/release.pass.cpp
index 9dfdd0b0ded2f..412b9ba023827 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/release.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/release.pass.cpp
@@ -5,8 +5,7 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
-//
-// UNSUPPORTED: no-threads
+
 // UNSUPPORTED: c++03, c++11
 
 // <shared_mutex>
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/op_bool.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/op_bool.pass.cpp
index 1186671ad04d2..e26e8122ab191 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/op_bool.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/op_bool.pass.cpp
@@ -5,8 +5,7 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
-//
-// UNSUPPORTED: no-threads
+
 // UNSUPPORTED: c++03, c++11
 
 // <shared_mutex>
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock.pass.cpp
index 4cf5ec2ab5ccf..9c6a971bc9f33 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock.pass.cpp
@@ -5,8 +5,7 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
-//
-// UNSUPPORTED: no-threads
+
 // UNSUPPORTED: c++03
 // ALLOW_RETRIES: 2
 
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_for.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_for.pass.cpp
index 8e7004e5eec85..b211ce3afce07 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_for.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_for.pass.cpp
@@ -5,8 +5,7 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
-//
-// UNSUPPORTED: no-threads
+
 // UNSUPPORTED: c++03
 
 // <mutex>
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_until.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_until.pass.cpp
index 077bc517399ab..67c0cb94e9f90 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_until.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_until.pass.cpp
@@ -5,8 +5,7 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
-//
-// UNSUPPORTED: no-threads
+
 // UNSUPPORTED: c++03
 
 // <mutex>
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/member_swap.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/member_swap.pass.cpp
index fc12d3baea202..79731dec09bd5 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/member_swap.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/member_swap.pass.cpp
@@ -5,8 +5,6 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
-//
-// UNSUPPORTED: no-threads
 
 // <mutex>
 
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/nonmember_swap.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/nonmember_swap.pass.cpp
index 03d268c4b9306..f4c1661556f94 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/nonmember_swap.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/nonmember_swap.pass.cpp
@@ -5,8 +5,6 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
-//
-// UNSUPPORTED: no-threads
 
 // <mutex>
 
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/release.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/release.pass.cpp
index 4f2d59c3d333d..fd2ed6dd5afb8 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/release.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/release.pass.cpp
@@ -5,8 +5,6 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
-//
-// UNSUPPORTED: no-threads
 
 // <mutex>
 

>From e06a8e6ebe3cc99a576b9bd27e990807fb15bb74 Mon Sep 17 00:00:00 2001
From: Petr Hosek <phosek at google.com>
Date: Sat, 13 Jul 2024 16:59:05 -0700
Subject: [PATCH 03/15] More tests

---
 .../thread.lock.guard/mutex.pass.cpp          | 28 ++++++++++---------
 .../thread.lock.shared.cons/mutex.pass.cpp    |  3 +-
 .../thread.lock.shared.locking/lock.pass.cpp  |  3 +-
 .../try_lock.pass.cpp                         |  3 +-
 4 files changed, 21 insertions(+), 16 deletions(-)

diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.pass.cpp
index 6025b0c3b465b..a95c2ef0029de 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.pass.cpp
@@ -18,27 +18,29 @@
 //     -> lock_guard<_Mutex>;  // C++17
 
 #include <mutex>
-#include <cstdlib>
 #include <cassert>
-
-#include "make_test_thread.h"
 #include "test_macros.h"
 
-std::mutex m;
+struct TestMutex {
+    bool locked = false;
+    TestMutex() = default;
+    ~TestMutex() { assert(!locked); }
 
-void do_try_lock() {
-  assert(m.try_lock() == false);
-}
+    void lock() { assert(!locked); locked = true; }
+    bool try_lock() { if (locked) return false; locked = true; return true; }
+    void unlock() { assert(locked); locked = false; }
+
+    TestMutex(TestMutex const&) = delete;
+    TestMutex& operator=(TestMutex const&) = delete;
+};
 
 int main(int, char**) {
+  TestMutex m;
   {
-    std::lock_guard<std::mutex> lg(m);
-    std::thread t = support::make_test_thread(do_try_lock);
-    t.join();
+    std::lock_guard<TestMutex> lg(m);
+    assert(m.locked);
   }
-
-  m.lock();
-  m.unlock();
+  assert(!m.locked);
 
 #if TEST_STD_VER >= 17
   std::lock_guard lg(m);
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex.pass.cpp
index ece330134f2cd..863948763e2ef 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex.pass.cpp
@@ -6,7 +6,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-// UNSUPPORTED: no-threads
 // UNSUPPORTED: c++03, c++11
 
 // <shared_mutex>
@@ -79,10 +78,12 @@ void test() {
 }
 
 int main(int, char**) {
+#ifndef TEST_HAS_NO_THREADS
 #if TEST_STD_VER >= 17
   test<std::shared_mutex>();
 #endif
   test<std::shared_timed_mutex>();
+#endif
   test<TrackedMutex>();
 
   // Use shared_lock with a dummy mutex class that tracks whether each
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/lock.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/lock.pass.cpp
index d36ca1d38f8f1..9097ac74d1272 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/lock.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/lock.pass.cpp
@@ -6,7 +6,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-// UNSUPPORTED: no-threads
 // UNSUPPORTED: c++03, c++11
 
 // <shared_mutex>
@@ -99,10 +98,12 @@ void test() {
 }
 
 int main(int, char**) {
+#ifndef TEST_HAS_NO_THREADS
 #if TEST_STD_VER >= 17
   test<std::shared_mutex>();
 #endif
   test<std::shared_timed_mutex>();
+#endif
   test<TrackedMutex>();
 
   // Use shared_lock with a dummy mutex class that tracks whether each
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock.pass.cpp
index b6146680b6e35..ccab79d4db016 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock.pass.cpp
@@ -6,7 +6,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-// UNSUPPORTED: no-threads
 // UNSUPPORTED: c++03, c++11
 
 // <shared_mutex>
@@ -104,10 +103,12 @@ void test() {
 }
 
 int main(int, char**) {
+#ifndef TEST_HAS_NO_THREADS
 #if TEST_STD_VER >= 17
   test<std::shared_mutex>();
 #endif
   test<std::shared_timed_mutex>();
+#endif
   test<TrackedMutex>();
 
   // Use shared_lock with a dummy mutex class that tracks whether each

>From 896cdc342ea226d06891cdf073294c424cee0fde Mon Sep 17 00:00:00 2001
From: Petr Hosek <phosek at google.com>
Date: Sat, 13 Jul 2024 17:38:15 -0700
Subject: [PATCH 04/15] Fix formatting

---
 libcxx/include/shared_mutex                   |  2 +-
 .../thread.lock.guard/mutex.pass.cpp          | 29 +++++++++++++------
 .../thread.lock.shared.cons/mutex.pass.cpp    |  4 +--
 .../thread.lock.shared.locking/lock.pass.cpp  |  4 +--
 .../try_lock.pass.cpp                         |  4 +--
 5 files changed, 27 insertions(+), 16 deletions(-)

diff --git a/libcxx/include/shared_mutex b/libcxx/include/shared_mutex
index 5918af4a214c1..63d24e0182fe5 100644
--- a/libcxx/include/shared_mutex
+++ b/libcxx/include/shared_mutex
@@ -305,7 +305,7 @@ bool shared_timed_mutex::try_lock_shared_until(const chrono::time_point<_Clock,
   return true;
 }
 
-#  endif   // !_LIBCPP_HAS_NO_THREADS
+#  endif // !_LIBCPP_HAS_NO_THREADS
 
 template <class _Mutex>
 class shared_lock {
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.pass.cpp
index a95c2ef0029de..ca902f16f81d7 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.pass.cpp
@@ -22,16 +22,27 @@
 #include "test_macros.h"
 
 struct TestMutex {
-    bool locked = false;
-    TestMutex() = default;
-    ~TestMutex() { assert(!locked); }
+  bool locked = false;
+  TestMutex() = default;
+  ~TestMutex() { assert(!locked); }
 
-    void lock() { assert(!locked); locked = true; }
-    bool try_lock() { if (locked) return false; locked = true; return true; }
-    void unlock() { assert(locked); locked = false; }
+  void lock() {
+    assert(!locked);
+    locked = true;
+  }
+  bool try_lock() {
+    if (locked)
+      return false;
+    locked = true;
+    return true;
+  }
+  void unlock() {
+    assert(locked);
+    locked = false;
+  }
 
-    TestMutex(TestMutex const&) = delete;
-    TestMutex& operator=(TestMutex const&) = delete;
+  TestMutex(TestMutex const&)            = delete;
+  TestMutex& operator=(TestMutex const&) = delete;
 };
 
 int main(int, char**) {
@@ -44,7 +55,7 @@ int main(int, char**) {
 
 #if TEST_STD_VER >= 17
   std::lock_guard lg(m);
-  static_assert((std::is_same<decltype(lg), std::lock_guard<decltype(m)>>::value), "" );
+  static_assert((std::is_same<decltype(lg), std::lock_guard<decltype(m)>>::value), "");
 #endif
 
   return 0;
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex.pass.cpp
index 863948763e2ef..c9d145addd63d 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex.pass.cpp
@@ -79,9 +79,9 @@ void test() {
 
 int main(int, char**) {
 #ifndef TEST_HAS_NO_THREADS
-#if TEST_STD_VER >= 17
+#  if TEST_STD_VER >= 17
   test<std::shared_mutex>();
-#endif
+#  endif
   test<std::shared_timed_mutex>();
 #endif
   test<TrackedMutex>();
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/lock.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/lock.pass.cpp
index 9097ac74d1272..3e0ef122ef990 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/lock.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/lock.pass.cpp
@@ -99,9 +99,9 @@ void test() {
 
 int main(int, char**) {
 #ifndef TEST_HAS_NO_THREADS
-#if TEST_STD_VER >= 17
+#  if TEST_STD_VER >= 17
   test<std::shared_mutex>();
-#endif
+#  endif
   test<std::shared_timed_mutex>();
 #endif
   test<TrackedMutex>();
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock.pass.cpp
index ccab79d4db016..d42b00414230c 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock.pass.cpp
@@ -104,9 +104,9 @@ void test() {
 
 int main(int, char**) {
 #ifndef TEST_HAS_NO_THREADS
-#if TEST_STD_VER >= 17
+#  if TEST_STD_VER >= 17
   test<std::shared_mutex>();
-#endif
+#  endif
   test<std::shared_timed_mutex>();
 #endif
   test<TrackedMutex>();

>From d717ad2d1f79c20e7fdd5101e6974b65f8ce5e84 Mon Sep 17 00:00:00 2001
From: Petr Hosek <phosek at google.com>
Date: Sat, 13 Jul 2024 21:30:37 -0700
Subject: [PATCH 05/15] Make defer_lock_t, try_to_lock_t and adopt_lock_t
 available also

---
 libcxx/include/__mutex/tag_types.h | 10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/libcxx/include/__mutex/tag_types.h b/libcxx/include/__mutex/tag_types.h
index 05ccb8b23a6f4..2b2dd58ee4e80 100644
--- a/libcxx/include/__mutex/tag_types.h
+++ b/libcxx/include/__mutex/tag_types.h
@@ -15,8 +15,6 @@
 #  pragma GCC system_header
 #endif
 
-#ifndef _LIBCPP_HAS_NO_THREADS
-
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 struct _LIBCPP_EXPORTED_FROM_ABI defer_lock_t {
@@ -31,18 +29,16 @@ struct _LIBCPP_EXPORTED_FROM_ABI adopt_lock_t {
   explicit adopt_lock_t() = default;
 };
 
-#  if _LIBCPP_STD_VER >= 17
+#if _LIBCPP_STD_VER >= 17
 inline constexpr defer_lock_t defer_lock   = defer_lock_t();
 inline constexpr try_to_lock_t try_to_lock = try_to_lock_t();
 inline constexpr adopt_lock_t adopt_lock   = adopt_lock_t();
-#  elif !defined(_LIBCPP_CXX03_LANG)
+#elif !defined(_LIBCPP_CXX03_LANG)
 constexpr defer_lock_t defer_lock   = defer_lock_t();
 constexpr try_to_lock_t try_to_lock = try_to_lock_t();
 constexpr adopt_lock_t adopt_lock   = adopt_lock_t();
-#  endif
+#endif
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_HAS_NO_THREADS
-
 #endif // _LIBCPP___MUTEX_TAG_TYPES_H

>From 252198dcfe05fdf1bb109c1ff8003bd3e0bd61b7 Mon Sep 17 00:00:00 2001
From: Petr Hosek <phosek at google.com>
Date: Sun, 14 Jul 2024 17:57:51 -0700
Subject: [PATCH 06/15] Make std::lock and std::try_lock available also

---
 libcxx/include/mutex | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/libcxx/include/mutex b/libcxx/include/mutex
index d4d7539240094..efae5544eab09 100644
--- a/libcxx/include/mutex
+++ b/libcxx/include/mutex
@@ -322,6 +322,8 @@ bool recursive_timed_mutex::try_lock_until(const chrono::time_point<_Clock, _Dur
   return false;
 }
 
+#endif // !_LIBCPP_HAS_NO_THREADS
+
 template <class _L0, class _L1>
 _LIBCPP_HIDE_FROM_ABI int try_lock(_L0& __l0, _L1& __l1) {
   unique_lock<_L0> __u0(__l0, try_to_lock_t());
@@ -335,7 +337,7 @@ _LIBCPP_HIDE_FROM_ABI int try_lock(_L0& __l0, _L1& __l1) {
   return 0;
 }
 
-#  ifndef _LIBCPP_CXX03_LANG
+#ifndef _LIBCPP_CXX03_LANG
 
 template <class _L0, class _L1, class _L2, class... _L3>
 _LIBCPP_HIDE_FROM_ABI int try_lock(_L0& __l0, _L1& __l1, _L2& __l2, _L3&... __l3) {
@@ -351,7 +353,7 @@ _LIBCPP_HIDE_FROM_ABI int try_lock(_L0& __l0, _L1& __l1, _L2& __l2, _L3&... __l3
   return __r;
 }
 
-#  endif // _LIBCPP_CXX03_LANG
+#endif // _LIBCPP_CXX03_LANG
 
 template <class _L0, class _L1>
 _LIBCPP_HIDE_FROM_ABI void lock(_L0& __l0, _L1& __l1) {
@@ -375,7 +377,7 @@ _LIBCPP_HIDE_FROM_ABI void lock(_L0& __l0, _L1& __l1) {
   }
 }
 
-#  ifndef _LIBCPP_CXX03_LANG
+#ifndef _LIBCPP_CXX03_LANG
 
 template <class _L0, class _L1, class _L2, class... _L3>
 void __lock_first(int __i, _L0& __l0, _L1& __l1, _L2& __l2, _L3&... __l3) {
@@ -418,8 +420,7 @@ inline _LIBCPP_HIDE_FROM_ABI void lock(_L0& __l0, _L1& __l1, _L2& __l2, _L3&...
   std::__lock_first(0, __l0, __l1, __l2, __l3...);
 }
 
-#  endif // _LIBCPP_CXX03_LANG
-#endif   // !_LIBCPP_HAS_NO_THREADS
+#endif // _LIBCPP_CXX03_LANG
 
 #if _LIBCPP_STD_VER >= 17
 template <class... _Mutexes>

>From 3ffe2d1a27378ffc6c4e32bd0445c4e47722db6d Mon Sep 17 00:00:00 2001
From: Petr Hosek <phosek at google.com>
Date: Sun, 14 Jul 2024 23:39:30 -0700
Subject: [PATCH 07/15] Exclude std::unique_lock, std::scoped_lock and
 std::shared_lock

---
 libcxx/include/__mutex/unique_lock.h              |  4 ++++
 libcxx/include/mutex                              | 15 +++++++--------
 libcxx/include/shared_mutex                       | 15 ++++++++-------
 .../thread.lock.scoped/adopt_lock.pass.cpp        |  3 ++-
 .../thread.lock/thread.lock.scoped/mutex.pass.cpp |  3 ++-
 .../thread.lock.shared.cons/mutex.pass.cpp        |  7 +++----
 .../thread.lock.shared.locking/lock.pass.cpp      |  7 +++----
 .../thread.lock.shared.locking/try_lock.pass.cpp  |  7 +++----
 .../try_lock_for.pass.cpp                         |  3 ++-
 .../try_lock_until.pass.cpp                       |  3 ++-
 .../thread.lock.shared.locking/unlock.pass.cpp    |  3 ++-
 .../thread.lock.shared.mod/member_swap.pass.cpp   |  3 ++-
 .../nonmember_swap.pass.cpp                       |  3 ++-
 .../thread.lock.shared.mod/release.pass.cpp       |  3 ++-
 .../thread.lock.shared.obs/op_bool.pass.cpp       |  3 ++-
 .../thread.lock.unique.locking/try_lock.pass.cpp  |  3 ++-
 .../try_lock_for.pass.cpp                         |  3 ++-
 .../try_lock_until.pass.cpp                       |  3 ++-
 .../thread.lock.unique.mod/member_swap.pass.cpp   |  2 ++
 .../nonmember_swap.pass.cpp                       |  2 ++
 .../thread.lock.unique.mod/release.pass.cpp       |  2 ++
 21 files changed, 58 insertions(+), 39 deletions(-)

diff --git a/libcxx/include/__mutex/unique_lock.h b/libcxx/include/__mutex/unique_lock.h
index 5df791de4c742..4a616ba51ee1c 100644
--- a/libcxx/include/__mutex/unique_lock.h
+++ b/libcxx/include/__mutex/unique_lock.h
@@ -22,6 +22,8 @@
 #  pragma GCC system_header
 #endif
 
+#ifndef _LIBCPP_HAS_NO_THREADS
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Mutex>
@@ -170,4 +172,6 @@ inline _LIBCPP_HIDE_FROM_ABI void swap(unique_lock<_Mutex>& __x, unique_lock<_Mu
 
 _LIBCPP_END_NAMESPACE_STD
 
+#endif // _LIBCPP_HAS_NO_THREADS
+
 #endif // _LIBCPP___MUTEX_UNIQUE_LOCK_H
diff --git a/libcxx/include/mutex b/libcxx/include/mutex
index efae5544eab09..02c52dd72f02b 100644
--- a/libcxx/include/mutex
+++ b/libcxx/include/mutex
@@ -322,8 +322,6 @@ bool recursive_timed_mutex::try_lock_until(const chrono::time_point<_Clock, _Dur
   return false;
 }
 
-#endif // !_LIBCPP_HAS_NO_THREADS
-
 template <class _L0, class _L1>
 _LIBCPP_HIDE_FROM_ABI int try_lock(_L0& __l0, _L1& __l1) {
   unique_lock<_L0> __u0(__l0, try_to_lock_t());
@@ -337,7 +335,7 @@ _LIBCPP_HIDE_FROM_ABI int try_lock(_L0& __l0, _L1& __l1) {
   return 0;
 }
 
-#ifndef _LIBCPP_CXX03_LANG
+#  ifndef _LIBCPP_CXX03_LANG
 
 template <class _L0, class _L1, class _L2, class... _L3>
 _LIBCPP_HIDE_FROM_ABI int try_lock(_L0& __l0, _L1& __l1, _L2& __l2, _L3&... __l3) {
@@ -353,7 +351,7 @@ _LIBCPP_HIDE_FROM_ABI int try_lock(_L0& __l0, _L1& __l1, _L2& __l2, _L3&... __l3
   return __r;
 }
 
-#endif // _LIBCPP_CXX03_LANG
+#  endif // _LIBCPP_CXX03_LANG
 
 template <class _L0, class _L1>
 _LIBCPP_HIDE_FROM_ABI void lock(_L0& __l0, _L1& __l1) {
@@ -377,7 +375,7 @@ _LIBCPP_HIDE_FROM_ABI void lock(_L0& __l0, _L1& __l1) {
   }
 }
 
-#ifndef _LIBCPP_CXX03_LANG
+#  ifndef _LIBCPP_CXX03_LANG
 
 template <class _L0, class _L1, class _L2, class... _L3>
 void __lock_first(int __i, _L0& __l0, _L1& __l1, _L2& __l2, _L3&... __l3) {
@@ -420,9 +418,9 @@ inline _LIBCPP_HIDE_FROM_ABI void lock(_L0& __l0, _L1& __l1, _L2& __l2, _L3&...
   std::__lock_first(0, __l0, __l1, __l2, __l3...);
 }
 
-#endif // _LIBCPP_CXX03_LANG
+#  endif // _LIBCPP_CXX03_LANG
 
-#if _LIBCPP_STD_VER >= 17
+#  if _LIBCPP_STD_VER >= 17
 template <class... _Mutexes>
 class _LIBCPP_TEMPLATE_VIS scoped_lock;
 
@@ -493,7 +491,8 @@ private:
 };
 _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(scoped_lock);
 
-#endif // _LIBCPP_STD_VER >= 17
+#  endif // _LIBCPP_STD_VER >= 17
+#endif   // !_LIBCPP_HAS_NO_THREADS
 
 _LIBCPP_END_NAMESPACE_STD
 
diff --git a/libcxx/include/shared_mutex b/libcxx/include/shared_mutex
index 63d24e0182fe5..397ac290d9b2e 100644
--- a/libcxx/include/shared_mutex
+++ b/libcxx/include/shared_mutex
@@ -122,11 +122,16 @@ template <class Mutex>
 
 */
 
+#include <__config>
+
+#ifdef _LIBCPP_HAS_NO_THREADS
+#  error "<shared_mutex> is not supported since libc++ has been configured without support for threads."
+#endif
+
 #include <__chrono/duration.h>
 #include <__chrono/steady_clock.h>
 #include <__chrono/time_point.h>
 #include <__condition_variable/condition_variable.h>
-#include <__config>
 #include <__memory/addressof.h>
 #include <__mutex/mutex.h>
 #include <__mutex/tag_types.h>
@@ -147,8 +152,6 @@ _LIBCPP_PUSH_MACROS
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#  ifndef _LIBCPP_HAS_NO_THREADS
-
 struct _LIBCPP_EXPORTED_FROM_ABI __shared_mutex_base {
   mutex __mut_;
   condition_variable __gate1_;
@@ -178,7 +181,7 @@ struct _LIBCPP_EXPORTED_FROM_ABI __shared_mutex_base {
   //     native_handle_type native_handle(); // See 30.2.3
 };
 
-#    if _LIBCPP_STD_VER >= 17
+#  if _LIBCPP_STD_VER >= 17
 class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_THREAD_SAFETY_ANNOTATION(__capability__("shared_mutex")) shared_mutex {
   __shared_mutex_base __base_;
 
@@ -215,7 +218,7 @@ public:
   //     typedef __shared_mutex_base::native_handle_type native_handle_type;
   //     _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return __base::unlock_shared(); }
 };
-#    endif
+#  endif
 
 class _LIBCPP_EXPORTED_FROM_ABI
 _LIBCPP_THREAD_SAFETY_ANNOTATION(__capability__("shared_timed_mutex")) shared_timed_mutex {
@@ -305,8 +308,6 @@ bool shared_timed_mutex::try_lock_shared_until(const chrono::time_point<_Clock,
   return true;
 }
 
-#  endif // !_LIBCPP_HAS_NO_THREADS
-
 template <class _Mutex>
 class shared_lock {
 public:
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.scoped/adopt_lock.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.scoped/adopt_lock.pass.cpp
index a48caf7fdbb51..83b29ff669dca 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.scoped/adopt_lock.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.scoped/adopt_lock.pass.cpp
@@ -5,7 +5,8 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
-
+//
+// UNSUPPORTED: no-threads
 // UNSUPPORTED: c++03, c++11, c++14
 
 // <mutex>
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.scoped/mutex.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.scoped/mutex.pass.cpp
index 0812c33c22226..f953fa4f8d6df 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.scoped/mutex.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.scoped/mutex.pass.cpp
@@ -5,7 +5,8 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
-
+//
+// UNSUPPORTED: no-threads
 // UNSUPPORTED: c++03, c++11, c++14
 
 // <mutex>
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex.pass.cpp
index c9d145addd63d..ece330134f2cd 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex.pass.cpp
@@ -6,6 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: no-threads
 // UNSUPPORTED: c++03, c++11
 
 // <shared_mutex>
@@ -78,12 +79,10 @@ void test() {
 }
 
 int main(int, char**) {
-#ifndef TEST_HAS_NO_THREADS
-#  if TEST_STD_VER >= 17
+#if TEST_STD_VER >= 17
   test<std::shared_mutex>();
-#  endif
-  test<std::shared_timed_mutex>();
 #endif
+  test<std::shared_timed_mutex>();
   test<TrackedMutex>();
 
   // Use shared_lock with a dummy mutex class that tracks whether each
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/lock.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/lock.pass.cpp
index 3e0ef122ef990..d36ca1d38f8f1 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/lock.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/lock.pass.cpp
@@ -6,6 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: no-threads
 // UNSUPPORTED: c++03, c++11
 
 // <shared_mutex>
@@ -98,12 +99,10 @@ void test() {
 }
 
 int main(int, char**) {
-#ifndef TEST_HAS_NO_THREADS
-#  if TEST_STD_VER >= 17
+#if TEST_STD_VER >= 17
   test<std::shared_mutex>();
-#  endif
-  test<std::shared_timed_mutex>();
 #endif
+  test<std::shared_timed_mutex>();
   test<TrackedMutex>();
 
   // Use shared_lock with a dummy mutex class that tracks whether each
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock.pass.cpp
index d42b00414230c..b6146680b6e35 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock.pass.cpp
@@ -6,6 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: no-threads
 // UNSUPPORTED: c++03, c++11
 
 // <shared_mutex>
@@ -103,12 +104,10 @@ void test() {
 }
 
 int main(int, char**) {
-#ifndef TEST_HAS_NO_THREADS
-#  if TEST_STD_VER >= 17
+#if TEST_STD_VER >= 17
   test<std::shared_mutex>();
-#  endif
-  test<std::shared_timed_mutex>();
 #endif
+  test<std::shared_timed_mutex>();
   test<TrackedMutex>();
 
   // Use shared_lock with a dummy mutex class that tracks whether each
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_for.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_for.pass.cpp
index 3b3c34f0b9351..d28ae395ccb0d 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_for.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_for.pass.cpp
@@ -5,7 +5,8 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
-
+//
+// UNSUPPORTED: no-threads
 // UNSUPPORTED: c++03, c++11
 
 // <shared_mutex>
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_until.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_until.pass.cpp
index ab5f3c7b6a935..880bf1cbd4999 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_until.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_until.pass.cpp
@@ -5,7 +5,8 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
-
+//
+// UNSUPPORTED: no-threads
 // UNSUPPORTED: c++03, c++11
 
 // <shared_mutex>
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/unlock.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/unlock.pass.cpp
index 0fcab6d346699..4f31a75f68dec 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/unlock.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/unlock.pass.cpp
@@ -5,7 +5,8 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
-
+//
+// UNSUPPORTED: no-threads
 // UNSUPPORTED: c++03, c++11
 
 // <shared_mutex>
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/member_swap.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/member_swap.pass.cpp
index af904434efd82..aeca2022ba9c9 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/member_swap.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/member_swap.pass.cpp
@@ -5,7 +5,8 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
-
+//
+// UNSUPPORTED: no-threads
 // UNSUPPORTED: c++03, c++11
 
 // <shared_mutex>
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/nonmember_swap.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/nonmember_swap.pass.cpp
index a2827b0292e76..25e5cf624caa8 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/nonmember_swap.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/nonmember_swap.pass.cpp
@@ -5,7 +5,8 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
-
+//
+// UNSUPPORTED: no-threads
 // UNSUPPORTED: c++03, c++11
 
 // <shared_mutex>
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/release.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/release.pass.cpp
index 412b9ba023827..9dfdd0b0ded2f 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/release.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/release.pass.cpp
@@ -5,7 +5,8 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
-
+//
+// UNSUPPORTED: no-threads
 // UNSUPPORTED: c++03, c++11
 
 // <shared_mutex>
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/op_bool.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/op_bool.pass.cpp
index e26e8122ab191..1186671ad04d2 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/op_bool.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/op_bool.pass.cpp
@@ -5,7 +5,8 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
-
+//
+// UNSUPPORTED: no-threads
 // UNSUPPORTED: c++03, c++11
 
 // <shared_mutex>
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock.pass.cpp
index 9c6a971bc9f33..4cf5ec2ab5ccf 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock.pass.cpp
@@ -5,7 +5,8 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
-
+//
+// UNSUPPORTED: no-threads
 // UNSUPPORTED: c++03
 // ALLOW_RETRIES: 2
 
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_for.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_for.pass.cpp
index b211ce3afce07..8e7004e5eec85 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_for.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_for.pass.cpp
@@ -5,7 +5,8 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
-
+//
+// UNSUPPORTED: no-threads
 // UNSUPPORTED: c++03
 
 // <mutex>
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_until.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_until.pass.cpp
index 67c0cb94e9f90..077bc517399ab 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_until.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_until.pass.cpp
@@ -5,7 +5,8 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
-
+//
+// UNSUPPORTED: no-threads
 // UNSUPPORTED: c++03
 
 // <mutex>
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/member_swap.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/member_swap.pass.cpp
index 79731dec09bd5..fc12d3baea202 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/member_swap.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/member_swap.pass.cpp
@@ -5,6 +5,8 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: no-threads
 
 // <mutex>
 
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/nonmember_swap.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/nonmember_swap.pass.cpp
index f4c1661556f94..03d268c4b9306 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/nonmember_swap.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/nonmember_swap.pass.cpp
@@ -5,6 +5,8 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: no-threads
 
 // <mutex>
 
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/release.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/release.pass.cpp
index fd2ed6dd5afb8..4f2d59c3d333d 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/release.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/release.pass.cpp
@@ -5,6 +5,8 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: no-threads
 
 // <mutex>
 

>From cd005429944aee2d0d885ac5d2808aebf8fbf006 Mon Sep 17 00:00:00 2001
From: Petr Hosek <phosek at google.com>
Date: Mon, 15 Jul 2024 15:59:09 -0700
Subject: [PATCH 08/15] Update tests

---
 ...mpile.fail.cpp => assign.compile.pass.cpp} | 12 +---
 ...compile.fail.cpp => copy.compile.pass.cpp} | 10 +---
 .../thread.lock.guard/lock.pass.cpp           | 56 +++++++++++++++++++
 .../thread.lock.guard/mutex.pass.cpp          | 41 +++++---------
 4 files changed, 76 insertions(+), 43 deletions(-)
 rename libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/{assign.compile.fail.cpp => assign.compile.pass.cpp} (73%)
 rename libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/{copy.compile.fail.cpp => copy.compile.pass.cpp} (76%)
 create mode 100644 libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/lock.pass.cpp

diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/assign.compile.fail.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/assign.compile.pass.cpp
similarity index 73%
rename from libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/assign.compile.fail.cpp
rename to libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/assign.compile.pass.cpp
index 330cae19d1fea..073090b3ec1ee 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/assign.compile.fail.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/assign.compile.pass.cpp
@@ -6,8 +6,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-// UNSUPPORTED: no-threads
-
 // <mutex>
 
 // template <class Mutex> class lock_guard;
@@ -16,13 +14,9 @@
 
 #include <mutex>
 
-int main(int, char**)
-{
-    std::mutex m0;
-    std::mutex m1;
-    std::lock_guard<std::mutex> lg0(m0);
-    std::lock_guard<std::mutex> lg(m1);
-    lg = lg0;
+class Lock;
 
+int main(int, char**) {
+  static_assert(!std::is_copy_assignable<std::lock_guard<Lock>>::value, "");
   return 0;
 }
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/copy.compile.fail.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/copy.compile.pass.cpp
similarity index 76%
rename from libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/copy.compile.fail.cpp
rename to libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/copy.compile.pass.cpp
index 7e9dd43a6bb32..c3911182be032 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/copy.compile.fail.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/copy.compile.pass.cpp
@@ -6,8 +6,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-// UNSUPPORTED: no-threads
-
 // <mutex>
 
 // template <class Mutex> class lock_guard;
@@ -16,11 +14,9 @@
 
 #include <mutex>
 
-int main(int, char**)
-{
-    std::mutex m;
-    std::lock_guard<std::mutex> lg0(m);
-    std::lock_guard<std::mutex> lg(lg0);
+class Lock;
 
+int main(int, char**) {
+  static_assert(!std::is_copy_constructible<std::lock_guard<Lock>>::value, "");
   return 0;
 }
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/lock.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/lock.pass.cpp
new file mode 100644
index 0000000000000..e2d05654f7862
--- /dev/null
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/lock.pass.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+
+// <mutex>
+
+// template <class Mutex> class lock_guard;
+
+// explicit lock_guard(mutex_type& m);
+
+// template<class _Mutex> lock_guard(lock_guard<_Mutex>)
+//     -> lock_guard<_Mutex>;  // C++17
+
+#include <mutex>
+#include <cassert>
+#include "test_macros.h"
+
+struct Lock {
+  bool locked = false;
+
+  Lock() = default;
+  ~Lock() { assert(!locked); }
+
+  void lock() {
+    assert(!locked);
+    locked = true;
+  }
+  void unlock() {
+    assert(locked);
+    locked = false;
+  }
+
+  Lock(Lock const&)            = delete;
+  Lock& operator=(Lock const&) = delete;
+};
+
+int main(int, char**) {
+  Lock l;
+  {
+    std::lock_guard<Lock> lg(l);
+    assert(l.locked);
+  }
+  assert(!l.locked);
+
+#if TEST_STD_VER >= 17
+  std::lock_guard lg(l);
+  static_assert((std::is_same<decltype(l), std::lock_guard<decltype(l)>>::value), "");
+#endif
+
+  return 0;
+}
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.pass.cpp
index ca902f16f81d7..6025b0c3b465b 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.pass.cpp
@@ -18,44 +18,31 @@
 //     -> lock_guard<_Mutex>;  // C++17
 
 #include <mutex>
+#include <cstdlib>
 #include <cassert>
+
+#include "make_test_thread.h"
 #include "test_macros.h"
 
-struct TestMutex {
-  bool locked = false;
-  TestMutex() = default;
-  ~TestMutex() { assert(!locked); }
+std::mutex m;
 
-  void lock() {
-    assert(!locked);
-    locked = true;
-  }
-  bool try_lock() {
-    if (locked)
-      return false;
-    locked = true;
-    return true;
-  }
-  void unlock() {
-    assert(locked);
-    locked = false;
-  }
-
-  TestMutex(TestMutex const&)            = delete;
-  TestMutex& operator=(TestMutex const&) = delete;
-};
+void do_try_lock() {
+  assert(m.try_lock() == false);
+}
 
 int main(int, char**) {
-  TestMutex m;
   {
-    std::lock_guard<TestMutex> lg(m);
-    assert(m.locked);
+    std::lock_guard<std::mutex> lg(m);
+    std::thread t = support::make_test_thread(do_try_lock);
+    t.join();
   }
-  assert(!m.locked);
+
+  m.lock();
+  m.unlock();
 
 #if TEST_STD_VER >= 17
   std::lock_guard lg(m);
-  static_assert((std::is_same<decltype(lg), std::lock_guard<decltype(m)>>::value), "");
+  static_assert((std::is_same<decltype(lg), std::lock_guard<decltype(m)>>::value), "" );
 #endif
 
   return 0;

>From 757a485ad22f2ff450a44217ef85d43af6e9ff1d Mon Sep 17 00:00:00 2001
From: Petr Hosek <phosek at google.com>
Date: Mon, 15 Jul 2024 16:09:52 -0700
Subject: [PATCH 09/15] Update test

---
 .../thread.lock.guard/lock.pass.cpp           | 22 +++++++++----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/lock.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/lock.pass.cpp
index e2d05654f7862..fc82b74165aaa 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/lock.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/lock.pass.cpp
@@ -20,11 +20,11 @@
 #include <cassert>
 #include "test_macros.h"
 
-struct Lock {
+struct MyMutex {
   bool locked = false;
 
-  Lock() = default;
-  ~Lock() { assert(!locked); }
+  MyMutex() = default;
+  ~MyMutex() { assert(!locked); }
 
   void lock() {
     assert(!locked);
@@ -35,21 +35,21 @@ struct Lock {
     locked = false;
   }
 
-  Lock(Lock const&)            = delete;
-  Lock& operator=(Lock const&) = delete;
+  MyMutex(MyMutex const&)            = delete;
+  MyMutex& operator=(MyMutex const&) = delete;
 };
 
 int main(int, char**) {
-  Lock l;
+  MyMutex m;
   {
-    std::lock_guard<Lock> lg(l);
-    assert(l.locked);
+    std::lock_guard<MyMutex> lg(m);
+    assert(m.locked);
   }
-  assert(!l.locked);
+  assert(!m.locked);
 
 #if TEST_STD_VER >= 17
-  std::lock_guard lg(l);
-  static_assert((std::is_same<decltype(l), std::lock_guard<decltype(l)>>::value), "");
+  std::lock_guard lg(m);
+  static_assert((std::is_same<decltype(lg), std::lock_guard<decltype(m)>>::value), "");
 #endif
 
   return 0;

>From 38d2425d3256211423c43ab30b17c3529351c451 Mon Sep 17 00:00:00 2001
From: Petr Hosek <phosek at google.com>
Date: Mon, 15 Jul 2024 22:36:38 -0700
Subject: [PATCH 10/15] Update tests

---
 .../thread.lock.guard/adopt_lock.pass.cpp     | 31 +++++++++++++------
 .../thread.lock.guard/assign.compile.pass.cpp |  4 +--
 .../thread.lock.guard/copy.compile.pass.cpp   |  4 +--
 .../thread.lock.guard/implicit_ctad.pass.cpp  | 12 ++++---
 .../thread.lock.guard/lock.pass.cpp           |  6 ++--
 .../thread.lock.guard/mutex.verify.cpp        |  8 ++---
 .../thread.lock.guard/types.pass.cpp          |  8 ++---
 7 files changed, 45 insertions(+), 28 deletions(-)

diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/adopt_lock.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/adopt_lock.pass.cpp
index 4d11674f1e83c..c0b976ded1d6d 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/adopt_lock.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/adopt_lock.pass.cpp
@@ -5,8 +5,7 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
-//
-// UNSUPPORTED: no-threads
+
 // UNSUPPORTED: c++03
 
 // <mutex>
@@ -19,21 +18,33 @@
 #include <cstdlib>
 #include <cassert>
 
-#include "make_test_thread.h"
 #include "test_macros.h"
 
-std::mutex m;
+struct MyMutex {
+  bool locked = false;
 
-void do_try_lock() {
-  assert(m.try_lock() == false);
-}
+  MyMutex() = default;
+  ~MyMutex() { assert(!locked); }
+
+  void lock() {
+    assert(!locked);
+    locked = true;
+  }
+  void unlock() {
+    assert(locked);
+    locked = false;
+  }
+
+  MyMutex(MyMutex const&)            = delete;
+  MyMutex& operator=(MyMutex const&) = delete;
+};
 
 int main(int, char**) {
+  MyMutex m;
   {
     m.lock();
-    std::lock_guard<std::mutex> lg(m, std::adopt_lock);
-    std::thread t = support::make_test_thread(do_try_lock);
-    t.join();
+    std::lock_guard<MyMutex> lg(m, std::adopt_lock);
+    assert(m.locked);
   }
 
   m.lock();
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/assign.compile.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/assign.compile.pass.cpp
index 073090b3ec1ee..431b057befa58 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/assign.compile.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/assign.compile.pass.cpp
@@ -14,9 +14,9 @@
 
 #include <mutex>
 
-class Lock;
+class MyMutex;
 
 int main(int, char**) {
-  static_assert(!std::is_copy_assignable<std::lock_guard<Lock>>::value, "");
+  static_assert(!std::is_copy_assignable<std::lock_guard<MyMutex> >::value, "");
   return 0;
 }
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/copy.compile.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/copy.compile.pass.cpp
index c3911182be032..36c8dc9951dff 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/copy.compile.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/copy.compile.pass.cpp
@@ -14,9 +14,9 @@
 
 #include <mutex>
 
-class Lock;
+class MyMutex;
 
 int main(int, char**) {
-  static_assert(!std::is_copy_constructible<std::lock_guard<Lock>>::value, "");
+  static_assert(!std::is_copy_constructible<std::lock_guard<MyMutex> >::value, "");
   return 0;
 }
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/implicit_ctad.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/implicit_ctad.pass.cpp
index 9319ec0dba04e..da3302d5d9c96 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/implicit_ctad.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/implicit_ctad.pass.cpp
@@ -6,7 +6,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-// UNSUPPORTED: no-threads
 // UNSUPPORTED: c++03, c++11, c++14
 
 // <mutex>
@@ -19,11 +18,16 @@
 
 #include "test_macros.h"
 
+struct MyMutex {
+  void lock() {}
+  void unlock() {}
+};
+
 int main(int, char**) {
-  std::mutex mutex;
+  MyMutex m;
   {
-    std::lock_guard lock(mutex);
-    ASSERT_SAME_TYPE(decltype(lock), std::lock_guard<std::mutex>);
+    std::lock_guard lg(m);
+    ASSERT_SAME_TYPE(decltype(lg), std::lock_guard<MyMutex>);
   }
 
   return 0;
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/lock.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/lock.pass.cpp
index fc82b74165aaa..6f86fdc63f100 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/lock.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/lock.pass.cpp
@@ -5,7 +5,6 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
-//
 
 // <mutex>
 
@@ -18,6 +17,7 @@
 
 #include <mutex>
 #include <cassert>
+
 #include "test_macros.h"
 
 struct MyMutex {
@@ -45,7 +45,9 @@ int main(int, char**) {
     std::lock_guard<MyMutex> lg(m);
     assert(m.locked);
   }
-  assert(!m.locked);
+
+  m.lock();
+  m.unlock();
 
 #if TEST_STD_VER >= 17
   std::lock_guard lg(m);
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.verify.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.verify.cpp
index 82f672891c452..b0ae0c8c57155 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.verify.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.verify.cpp
@@ -6,8 +6,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-// UNSUPPORTED: no-threads
-
 // <mutex>
 
 // template <class Mutex> class lock_guard;
@@ -16,10 +14,12 @@
 
 #include <mutex>
 
+struct MyMutex {};
+
 int main(int, char**)
 {
-    std::mutex m;
-    std::lock_guard<std::mutex> lg = m; // expected-error{{no viable conversion}}
+  MyMutex m;
+  std::lock_guard<MyMutex> lg = m; // expected-error{{no viable conversion}}
 
   return 0;
 }
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/types.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/types.pass.cpp
index 8b10d9dab8f2a..5d5aefd80f9ac 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/types.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/types.pass.cpp
@@ -5,8 +5,6 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
-//
-// UNSUPPORTED: no-threads
 
 // <mutex>
 
@@ -23,10 +21,12 @@
 
 #include "test_macros.h"
 
+struct MyMutex {};
+
 int main(int, char**)
 {
-    static_assert((std::is_same<std::lock_guard<std::mutex>::mutex_type,
-                   std::mutex>::value), "");
+  static_assert((std::is_same<std::lock_guard<MyMutex>::mutex_type,
+                 MyMutex>::value), "");
 
   return 0;
 }

>From d7eb493d36695b56084a79447e311ae23511fd67 Mon Sep 17 00:00:00 2001
From: Petr Hosek <phosek at google.com>
Date: Mon, 15 Jul 2024 22:42:42 -0700
Subject: [PATCH 11/15] Fix formatting

---
 .../thread.lock/thread.lock.guard/types.pass.cpp            | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/types.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/types.pass.cpp
index 5d5aefd80f9ac..3d5cf03f29f4f 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/types.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/types.pass.cpp
@@ -23,10 +23,8 @@
 
 struct MyMutex {};
 
-int main(int, char**)
-{
-  static_assert((std::is_same<std::lock_guard<MyMutex>::mutex_type,
-                 MyMutex>::value), "");
+int main(int, char**) {
+  static_assert((std::is_same<std::lock_guard<MyMutex>::mutex_type, MyMutex>::value), "");
 
   return 0;
 }

>From f07b06468d4b32b526f9fc4c78717290dba3fe16 Mon Sep 17 00:00:00 2001
From: Petr Hosek <phosek at google.com>
Date: Tue, 16 Jul 2024 09:30:04 -0700
Subject: [PATCH 12/15] Extract helper class into a header

---
 .../thread.lock.guard/adopt_lock.pass.cpp     | 20 +--------------
 .../thread.lock.guard/assign.compile.pass.cpp |  7 ++----
 .../thread.lock.guard/copy.compile.pass.cpp   |  7 ++----
 .../{mutex.verify.cpp => ctor.mutex.pass.cpp} |  9 ++++---
 .../thread.lock.guard/implicit_ctad.pass.cpp  |  6 +----
 .../thread.lock.guard/lock.pass.cpp           | 20 +--------------
 ...{types.pass.cpp => types.compile.pass.cpp} |  9 ++-----
 .../thread.lock/thread.lock.guard/types.h     | 25 +++++++++++++++++++
 8 files changed, 39 insertions(+), 64 deletions(-)
 rename libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/{mutex.verify.cpp => ctor.mutex.pass.cpp} (68%)
 rename libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/{types.pass.cpp => types.compile.pass.cpp} (78%)
 create mode 100644 libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/types.h

diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/adopt_lock.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/adopt_lock.pass.cpp
index c0b976ded1d6d..b30e2bda96753 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/adopt_lock.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/adopt_lock.pass.cpp
@@ -18,27 +18,9 @@
 #include <cstdlib>
 #include <cassert>
 
+#include "types.h"
 #include "test_macros.h"
 
-struct MyMutex {
-  bool locked = false;
-
-  MyMutex() = default;
-  ~MyMutex() { assert(!locked); }
-
-  void lock() {
-    assert(!locked);
-    locked = true;
-  }
-  void unlock() {
-    assert(locked);
-    locked = false;
-  }
-
-  MyMutex(MyMutex const&)            = delete;
-  MyMutex& operator=(MyMutex const&) = delete;
-};
-
 int main(int, char**) {
   MyMutex m;
   {
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/assign.compile.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/assign.compile.pass.cpp
index 431b057befa58..abd37ea0d55dd 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/assign.compile.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/assign.compile.pass.cpp
@@ -14,9 +14,6 @@
 
 #include <mutex>
 
-class MyMutex;
+#include "types.h"
 
-int main(int, char**) {
-  static_assert(!std::is_copy_assignable<std::lock_guard<MyMutex> >::value, "");
-  return 0;
-}
+static_assert(!std::is_copy_assignable<std::lock_guard<MyMutex> >::value, "");
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/copy.compile.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/copy.compile.pass.cpp
index 36c8dc9951dff..2a5973726ff1d 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/copy.compile.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/copy.compile.pass.cpp
@@ -14,9 +14,6 @@
 
 #include <mutex>
 
-class MyMutex;
+#include "types.h"
 
-int main(int, char**) {
-  static_assert(!std::is_copy_constructible<std::lock_guard<MyMutex> >::value, "");
-  return 0;
-}
+static_assert(!std::is_copy_constructible<std::lock_guard<MyMutex> >::value, "");
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.verify.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/ctor.mutex.pass.cpp
similarity index 68%
rename from libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.verify.cpp
rename to libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/ctor.mutex.pass.cpp
index b0ae0c8c57155..4fd21c8ac4459 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.verify.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/ctor.mutex.pass.cpp
@@ -12,14 +12,15 @@
 
 // explicit lock_guard(mutex_type& m);
 
+#include <cassert>
 #include <mutex>
 
-struct MyMutex {};
+#include "types.h"
 
-int main(int, char**)
-{
+int main(int, char**) {
   MyMutex m;
-  std::lock_guard<MyMutex> lg = m; // expected-error{{no viable conversion}}
+  std::lock_guard<MyMutex> lg(m); // makes sure this compiles and runs
+  static_assert(!std::is_convertible_v<MyMutex, std::lock_guard<MyMutex>>, "constructor must be explicit");
 
   return 0;
 }
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/implicit_ctad.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/implicit_ctad.pass.cpp
index da3302d5d9c96..72dc3547815d4 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/implicit_ctad.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/implicit_ctad.pass.cpp
@@ -17,11 +17,7 @@
 #include <mutex>
 
 #include "test_macros.h"
-
-struct MyMutex {
-  void lock() {}
-  void unlock() {}
-};
+#include "types.h"
 
 int main(int, char**) {
   MyMutex m;
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/lock.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/lock.pass.cpp
index 6f86fdc63f100..fb146d5b318d3 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/lock.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/lock.pass.cpp
@@ -19,25 +19,7 @@
 #include <cassert>
 
 #include "test_macros.h"
-
-struct MyMutex {
-  bool locked = false;
-
-  MyMutex() = default;
-  ~MyMutex() { assert(!locked); }
-
-  void lock() {
-    assert(!locked);
-    locked = true;
-  }
-  void unlock() {
-    assert(locked);
-    locked = false;
-  }
-
-  MyMutex(MyMutex const&)            = delete;
-  MyMutex& operator=(MyMutex const&) = delete;
-};
+#include "types.h"
 
 int main(int, char**) {
   MyMutex m;
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/types.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/types.compile.pass.cpp
similarity index 78%
rename from libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/types.pass.cpp
rename to libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/types.compile.pass.cpp
index 3d5cf03f29f4f..eba76b83629ed 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/types.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/types.compile.pass.cpp
@@ -20,11 +20,6 @@
 #include <type_traits>
 
 #include "test_macros.h"
+#include "types.h"
 
-struct MyMutex {};
-
-int main(int, char**) {
-  static_assert((std::is_same<std::lock_guard<MyMutex>::mutex_type, MyMutex>::value), "");
-
-  return 0;
-}
+static_assert((std::is_same<std::lock_guard<MyMutex>::mutex_type, MyMutex>::value), "");
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/types.h b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/types.h
new file mode 100644
index 0000000000000..a3e0c4ed1ff25
--- /dev/null
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/types.h
@@ -0,0 +1,25 @@
+#ifndef TEST_STD_THREAD_THREAD_MUTEX_THREAD_LOCK_THREAD_LOCK_GUARD_TYPES_H
+#define TEST_STD_THREAD_THREAD_MUTEX_THREAD_LOCK_THREAD_LOCK_GUARD_TYPES_H
+
+#include <cassert>
+
+struct MyMutex {
+  bool locked = false;
+
+  MyMutex() = default;
+  ~MyMutex() { assert(!locked); }
+
+  void lock() {
+    assert(!locked);
+    locked = true;
+  }
+  void unlock() {
+    assert(locked);
+    locked = false;
+  }
+
+  MyMutex(MyMutex const&)            = delete;
+  MyMutex& operator=(MyMutex const&) = delete;
+};
+
+#endif // TEST_STD_THREAD_THREAD_MUTEX_THREAD_LOCK_THREAD_LOCK_GUARD_TYPES_H

>From da38a9f62eb374a2b1e6125afe3c13400cda4b89 Mon Sep 17 00:00:00 2001
From: Petr Hosek <phosek at google.com>
Date: Tue, 16 Jul 2024 09:50:06 -0700
Subject: [PATCH 13/15] Missing include

---
 .../thread.lock/thread.lock.guard/ctor.mutex.pass.cpp            | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/ctor.mutex.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/ctor.mutex.pass.cpp
index 4fd21c8ac4459..e1822de263d15 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/ctor.mutex.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/ctor.mutex.pass.cpp
@@ -14,6 +14,7 @@
 
 #include <cassert>
 #include <mutex>
+#include <type_traits>
 
 #include "types.h"
 

>From 5cdda4ad1a46aee80b9f5ea4ef6a9af1ab425c43 Mon Sep 17 00:00:00 2001
From: Petr Hosek <phosek at google.com>
Date: Tue, 16 Jul 2024 12:37:10 -0700
Subject: [PATCH 14/15] std::is_convertible_v is only available since C++17

---
 .../thread.lock/thread.lock.guard/ctor.mutex.pass.cpp          | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/ctor.mutex.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/ctor.mutex.pass.cpp
index e1822de263d15..8524c9741b5dc 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/ctor.mutex.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/ctor.mutex.pass.cpp
@@ -16,12 +16,15 @@
 #include <mutex>
 #include <type_traits>
 
+#include "test_macros.h"
 #include "types.h"
 
 int main(int, char**) {
   MyMutex m;
   std::lock_guard<MyMutex> lg(m); // makes sure this compiles and runs
+#if TEST_STD_VER >= 17
   static_assert(!std::is_convertible_v<MyMutex, std::lock_guard<MyMutex>>, "constructor must be explicit");
+#endif
 
   return 0;
 }

>From 9f95bb13c6691adc9248577618b2c24a81451779 Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Tue, 16 Jul 2024 15:51:01 -0400
Subject: [PATCH 15/15] Apply minor review comments

---
 ...lock.pass.cpp => ctor.adopt_lock.pass.cpp} |  8 +---
 .../thread.lock.guard/ctor.mutex.pass.cpp     | 10 ++---
 .../thread.lock.guard/implicit_ctad.pass.cpp  |  2 +-
 .../thread.lock.guard/lock.pass.cpp           | 40 -------------------
 ...{mutex.pass.cpp => mutex-interop.pass.cpp} | 33 +++++++--------
 .../thread.lock.guard/types.compile.pass.cpp  |  3 +-
 .../thread.lock/thread.lock.guard/types.h     |  8 ++++
 7 files changed, 31 insertions(+), 73 deletions(-)
 rename libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/{adopt_lock.pass.cpp => ctor.adopt_lock.pass.cpp} (89%)
 delete mode 100644 libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/lock.pass.cpp
 rename libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/{mutex.pass.cpp => mutex-interop.pass.cpp} (56%)

diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/adopt_lock.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/ctor.adopt_lock.pass.cpp
similarity index 89%
rename from libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/adopt_lock.pass.cpp
rename to libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/ctor.adopt_lock.pass.cpp
index b30e2bda96753..e9d2413ecd292 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/adopt_lock.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/ctor.adopt_lock.pass.cpp
@@ -15,22 +15,18 @@
 // lock_guard(mutex_type& m, adopt_lock_t);
 
 #include <mutex>
-#include <cstdlib>
 #include <cassert>
 
 #include "types.h"
-#include "test_macros.h"
 
 int main(int, char**) {
-  MyMutex m;
   {
+    MyMutex m;
     m.lock();
     std::lock_guard<MyMutex> lg(m, std::adopt_lock);
     assert(m.locked);
   }
-
-  m.lock();
-  m.unlock();
+  assert(!m.locked);
 
   return 0;
 }
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/ctor.mutex.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/ctor.mutex.pass.cpp
index 8524c9741b5dc..5f627e4243791 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/ctor.mutex.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/ctor.mutex.pass.cpp
@@ -16,15 +16,15 @@
 #include <mutex>
 #include <type_traits>
 
-#include "test_macros.h"
 #include "types.h"
 
 int main(int, char**) {
   MyMutex m;
-  std::lock_guard<MyMutex> lg(m); // makes sure this compiles and runs
-#if TEST_STD_VER >= 17
-  static_assert(!std::is_convertible_v<MyMutex, std::lock_guard<MyMutex>>, "constructor must be explicit");
-#endif
+  assert(!m.locked);
+  std::lock_guard<MyMutex> lg(m);
+  assert(m.locked);
+
+  static_assert(!std::is_convertible<MyMutex, std::lock_guard<MyMutex>>::value, "constructor must be explicit");
 
   return 0;
 }
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/implicit_ctad.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/implicit_ctad.pass.cpp
index 72dc3547815d4..cd5e6692731fe 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/implicit_ctad.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/implicit_ctad.pass.cpp
@@ -10,7 +10,7 @@
 
 // <mutex>
 
-// lock_guard
+// template <class Mutex> class lock_guard;
 
 // Make sure that the implicitly-generated CTAD works.
 
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/lock.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/lock.pass.cpp
deleted file mode 100644
index fb146d5b318d3..0000000000000
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/lock.pass.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// <mutex>
-
-// template <class Mutex> class lock_guard;
-
-// explicit lock_guard(mutex_type& m);
-
-// template<class _Mutex> lock_guard(lock_guard<_Mutex>)
-//     -> lock_guard<_Mutex>;  // C++17
-
-#include <mutex>
-#include <cassert>
-
-#include "test_macros.h"
-#include "types.h"
-
-int main(int, char**) {
-  MyMutex m;
-  {
-    std::lock_guard<MyMutex> lg(m);
-    assert(m.locked);
-  }
-
-  m.lock();
-  m.unlock();
-
-#if TEST_STD_VER >= 17
-  std::lock_guard lg(m);
-  static_assert((std::is_same<decltype(lg), std::lock_guard<decltype(m)>>::value), "");
-#endif
-
-  return 0;
-}
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex-interop.pass.cpp
similarity index 56%
rename from libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.pass.cpp
rename to libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex-interop.pass.cpp
index 6025b0c3b465b..49277861d15ca 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex-interop.pass.cpp
@@ -5,44 +5,39 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
-//
-// UNSUPPORTED: no-threads
-
-// <mutex>
 
-// template <class Mutex> class lock_guard;
-
-// explicit lock_guard(mutex_type& m);
+// UNSUPPORTED: no-threads
 
-// template<class _Mutex> lock_guard(lock_guard<_Mutex>)
-//     -> lock_guard<_Mutex>;  // C++17
+// Test the interoperation of std::lock_guard with std::mutex, since that is such
+// a common use case.
 
-#include <mutex>
-#include <cstdlib>
 #include <cassert>
+#include <mutex>
+#include <type_traits>
 
 #include "make_test_thread.h"
 #include "test_macros.h"
 
-std::mutex m;
-
-void do_try_lock() {
-  assert(m.try_lock() == false);
-}
+void do_try_lock(std::mutex& m) { assert(m.try_lock() == false); }
 
 int main(int, char**) {
   {
+    std::mutex m;
     std::lock_guard<std::mutex> lg(m);
-    std::thread t = support::make_test_thread(do_try_lock);
+    std::thread t = support::make_test_thread(do_try_lock, m);
     t.join();
   }
 
+  // This should work because the lock_guard unlocked the mutex when it was destroyed above.
   m.lock();
   m.unlock();
 
+  // Test CTAD
 #if TEST_STD_VER >= 17
-  std::lock_guard lg(m);
-  static_assert((std::is_same<decltype(lg), std::lock_guard<decltype(m)>>::value), "" );
+  {
+    std::lock_guard lg(m);
+    static_assert(std::is_same<decltype(lg), std::lock_guard<std::mutex>>::value, "");
+  }
 #endif
 
   return 0;
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/types.compile.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/types.compile.pass.cpp
index eba76b83629ed..015dbfe3c46ae 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/types.compile.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/types.compile.pass.cpp
@@ -19,7 +19,6 @@
 #include <mutex>
 #include <type_traits>
 
-#include "test_macros.h"
 #include "types.h"
 
-static_assert((std::is_same<std::lock_guard<MyMutex>::mutex_type, MyMutex>::value), "");
+static_assert(std::is_same<std::lock_guard<MyMutex>::mutex_type, MyMutex>::value, "");
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/types.h b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/types.h
index a3e0c4ed1ff25..5aeed21547880 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/types.h
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/types.h
@@ -1,3 +1,11 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
 #ifndef TEST_STD_THREAD_THREAD_MUTEX_THREAD_LOCK_THREAD_LOCK_GUARD_TYPES_H
 #define TEST_STD_THREAD_THREAD_MUTEX_THREAD_LOCK_THREAD_LOCK_GUARD_TYPES_H
 



More information about the libcxx-commits mailing list