[libcxx-commits] [libcxx] 6192f45 - [libc++] Make `std::lock_guard` available with `_LIBCPP_HAS_NO_THREADS` (#98717)
via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Jul 16 21:58:17 PDT 2024
Author: Petr Hosek
Date: 2024-07-16T21:58:13-07:00
New Revision: 6192f458f4fd2ca4e6f01515547034f89325e73c
URL: https://github.com/llvm/llvm-project/commit/6192f458f4fd2ca4e6f01515547034f89325e73c
DIFF: https://github.com/llvm/llvm-project/commit/6192f458f4fd2ca4e6f01515547034f89325e73c.diff
LOG: [libc++] Make `std::lock_guard` available with `_LIBCPP_HAS_NO_THREADS` (#98717)
This change makes `std::lock_guard` available when
`_LIBCPP_HAS_NO_THREADS` is set. This class is generic and doesn't
require threading support, and is regularly used even in environments
where threading isn't available like embedded.
fixes #89891
---------
Co-authored-by: Louis Dionne <ldionne.2 at gmail.com>
Added:
libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/assign.compile.pass.cpp
libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/copy.compile.pass.cpp
libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/ctor.adopt_lock.pass.cpp
libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/ctor.mutex.pass.cpp
libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/std.mutex.pass.cpp
libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/types.compile.pass.cpp
libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/types.h
Modified:
libcxx/include/__mutex/lock_guard.h
libcxx/include/__mutex/tag_types.h
libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/implicit_ctad.pass.cpp
Removed:
libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/adopt_lock.pass.cpp
libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/assign.compile.fail.cpp
libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/copy.compile.fail.cpp
libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.pass.cpp
libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.verify.cpp
libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/types.pass.cpp
################################################################################
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/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
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 74%
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 2d0f438ed0391..abd37ea0d55dd 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
@@ -14,13 +14,6 @@
#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;
+#include "types.h"
- 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.fail.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/copy.compile.pass.cpp
similarity index 78%
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 e99517e47e8c6..2a5973726ff1d 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
@@ -14,11 +14,6 @@
#include <mutex>
-int main(int, char**)
-{
- std::mutex m;
- std::lock_guard<std::mutex> lg0(m);
- std::lock_guard<std::mutex> lg(lg0);
+#include "types.h"
- 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/adopt_lock.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/ctor.adopt_lock.pass.cpp
similarity index 64%
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 4d11674f1e83c..d674b9a93fc64 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
@@ -5,8 +5,7 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
-//
-// UNSUPPORTED: no-threads
+
// UNSUPPORTED: c++03
// <mutex>
@@ -16,28 +15,18 @@
// lock_guard(mutex_type& m, adopt_lock_t);
#include <mutex>
-#include <cstdlib>
#include <cassert>
-#include "make_test_thread.h"
-#include "test_macros.h"
-
-std::mutex m;
-
-void do_try_lock() {
- assert(m.try_lock() == false);
-}
+#include "types.h"
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();
- m.unlock();
+ assert(!m.locked);
return 0;
}
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 63%
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 82f672891c452..9fcffd2f9957d 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
@@ -6,20 +6,25 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: no-threads
-
// <mutex>
// template <class Mutex> class lock_guard;
// explicit lock_guard(mutex_type& m);
+#include <cassert>
#include <mutex>
+#include <type_traits>
+
+#include "types.h"
+
+int main(int, char**) {
+ MyMutex m;
+ assert(!m.locked);
+ std::lock_guard<MyMutex> lg(m);
+ assert(m.locked);
-int main(int, char**)
-{
- std::mutex m;
- std::lock_guard<std::mutex> lg = m; // expected-error{{no viable conversion}}
+ 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 9319ec0dba04e..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
@@ -6,24 +6,24 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: no-threads
// UNSUPPORTED: c++03, c++11, c++14
// <mutex>
-// lock_guard
+// template <class Mutex> class lock_guard;
// Make sure that the implicitly-generated CTAD works.
#include <mutex>
#include "test_macros.h"
+#include "types.h"
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/mutex.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.pass.cpp
deleted file mode 100644
index 6025b0c3b465b..0000000000000
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.pass.cpp
+++ /dev/null
@@ -1,49 +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
-//
-//===----------------------------------------------------------------------===//
-//
-// UNSUPPORTED: no-threads
-
-// <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 <cstdlib>
-#include <cassert>
-
-#include "make_test_thread.h"
-#include "test_macros.h"
-
-std::mutex m;
-
-void do_try_lock() {
- assert(m.try_lock() == false);
-}
-
-int main(int, char**) {
- {
- std::lock_guard<std::mutex> lg(m);
- std::thread t = support::make_test_thread(do_try_lock);
- t.join();
- }
-
- 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/std.mutex.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/std.mutex.pass.cpp
new file mode 100644
index 0000000000000..5453db49d4e34
--- /dev/null
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/std.mutex.pass.cpp
@@ -0,0 +1,49 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: no-threads
+// UNSUPPORTED: c++03
+
+// Test the interoperation of std::lock_guard with std::mutex, since that is such
+// a common use case.
+
+#include <cassert>
+#include <mutex>
+#include <type_traits>
+#include <functional>
+
+#include "make_test_thread.h"
+#include "test_macros.h"
+
+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::ref(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::mutex m;
+ 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.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/types.compile.pass.cpp
similarity index 71%
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 8b10d9dab8f2a..015dbfe3c46ae 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
@@ -5,8 +5,6 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
-//
-// UNSUPPORTED: no-threads
// <mutex>
@@ -21,12 +19,6 @@
#include <mutex>
#include <type_traits>
-#include "test_macros.h"
-
-int main(int, char**)
-{
- static_assert((std::is_same<std::lock_guard<std::mutex>::mutex_type,
- std::mutex>::value), "");
+#include "types.h"
- 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..5aeed21547880
--- /dev/null
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/types.h
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+#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
More information about the libcxx-commits
mailing list