[libcxx-commits] [libcxx] [libc++] Refactor the std::unique_lock tests (PR #102151)
Nikolas Klauser via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Aug 20 01:21:15 PDT 2024
https://github.com/philnik777 updated https://github.com/llvm/llvm-project/pull/102151
>From 2ecf161210fa1a0957b29acc903433b65ee85c51 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Tue, 6 Aug 2024 16:18:01 +0200
Subject: [PATCH] [libc++] Refactor the std::unique_lock tests
---
...ass.cpp => implicit_ctad.compile.pass.cpp} | 14 +--
.../thread.lock.unique/mutex.pass.cpp | 68 ++++++++++++++
.../copy_assign.compile.pass.cpp | 4 +-
.../copy_ctor.compile.pass.cpp | 4 +-
.../thread.lock.unique.cons/default.pass.cpp | 9 +-
.../move_assign.pass.cpp | 41 +++------
.../move_ctor.pass.cpp | 39 ++++----
.../thread.lock.unique.cons/mutex.pass.cpp | 44 ++--------
.../mutex_adopt_lock.pass.cpp | 30 ++-----
.../mutex_defer_lock.pass.cpp | 31 +++----
.../mutex_duration.pass.cpp | 79 +++++------------
.../mutex_time_point.pass.cpp | 80 +++++------------
.../mutex_try_to_lock.pass.cpp | 72 +++++----------
.../thread.lock.unique.locking/lock.pass.cpp | 81 ++++++-----------
.../try_lock.pass.cpp | 41 +++++----
.../try_lock_for.pass.cpp | 43 +++++----
.../try_lock_until.pass.cpp | 39 ++++----
.../unlock.pass.cpp | 26 ++++--
.../member_swap.pass.cpp | 26 ++++--
.../nonmember_swap.pass.cpp | 26 ++++--
.../thread.lock.unique.mod/release.pass.cpp | 33 +++----
.../thread.lock.unique.obs/mutex.pass.cpp | 21 +++--
.../thread.lock.unique.obs/op_bool.pass.cpp | 24 ++---
.../thread.lock.unique.obs/owns_lock.pass.cpp | 21 +++--
.../thread.lock.unique/types.compile.pass.cpp | 5 +-
.../thread.lock/thread.lock.unique/types.h | 88 -------------------
libcxx/test/support/checking_mutex.h | 80 +++++++++++++++++
27 files changed, 502 insertions(+), 567 deletions(-)
rename libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/{implicit_ctad.pass.cpp => implicit_ctad.compile.pass.cpp} (71%)
create mode 100644 libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/mutex.pass.cpp
delete mode 100644 libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/types.h
create mode 100644 libcxx/test/support/checking_mutex.h
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/implicit_ctad.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/implicit_ctad.compile.pass.cpp
similarity index 71%
rename from libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/implicit_ctad.pass.cpp
rename to libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/implicit_ctad.compile.pass.cpp
index 8c7ca4279eead0..cc94c5704327fe 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/implicit_ctad.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/implicit_ctad.compile.pass.cpp
@@ -16,15 +16,7 @@
#include <mutex>
-#include "test_macros.h"
-#include "types.h"
+#include "checking_mutex.h"
-int main(int, char**) {
- MyMutex mutex;
- {
- std::unique_lock lock(mutex);
- ASSERT_SAME_TYPE(decltype(lock), std::unique_lock<MyMutex>);
- }
-
- return 0;
-}
+checking_mutex mux;
+static_assert(std::is_same_v<std::unique_lock<checking_mutex>, decltype(std::unique_lock{mux})>);
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/mutex.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/mutex.pass.cpp
new file mode 100644
index 00000000000000..3fe9dcaa98e6c6
--- /dev/null
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/mutex.pass.cpp
@@ -0,0 +1,68 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: c++03
+
+// <mutex>
+
+// Make sure std::unique_lock works with std::mutex as expected.
+
+#include <atomic>
+#include <cassert>
+#include <mutex>
+
+#include "make_test_thread.h"
+
+std::atomic<bool> keep_waiting;
+std::atomic<bool> child_thread_locked = false;
+std::mutex mux;
+bool main_thread_unlocked = false;
+bool child_thread_unlocked = false;
+
+void lock_thread() {
+ std::unique_lock<std::mutex> lock(mux);
+ assert(main_thread_unlocked);
+ main_thread_unlocked = false;
+ child_thread_unlocked = true;
+}
+
+void try_lock_thread() {
+ std::unique_lock<std::mutex> lock(mux, std::try_to_lock_t());
+ assert(lock.owns_lock());
+ child_thread_locked = true;
+
+ while (keep_waiting)
+ std::this_thread::sleep_for(std::chrono::milliseconds(10));
+
+ child_thread_unlocked = true;
+}
+
+int main(int, char**) {
+ {
+ mux.lock();
+ std::thread t = support::make_test_thread(lock_thread);
+ main_thread_unlocked = true;
+ mux.unlock();
+ t.join();
+ assert(child_thread_unlocked);
+ }
+
+ {
+ child_thread_unlocked = false;
+ keep_waiting = true;
+ std::thread t = support::make_test_thread(try_lock_thread);
+ while (!child_thread_locked)
+ std::this_thread::sleep_for(std::chrono::milliseconds(10));
+ assert(!mux.try_lock());
+ keep_waiting = false;
+ t.join();
+ assert(child_thread_unlocked);
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_assign.compile.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_assign.compile.pass.cpp
index 9ab8369637cdc5..c0cb7d4ddd27a6 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_assign.compile.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_assign.compile.pass.cpp
@@ -14,6 +14,6 @@
#include <mutex>
-#include "../types.h"
+#include "checking_mutex.h"
-static_assert(!std::is_copy_assignable<std::lock_guard<MyMutex> >::value, "");
+static_assert(!std::is_copy_assignable<std::lock_guard<checking_mutex> >::value, "");
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_ctor.compile.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_ctor.compile.pass.cpp
index e846061f5fbd08..2846b24125e784 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_ctor.compile.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_ctor.compile.pass.cpp
@@ -14,6 +14,6 @@
#include <mutex>
-#include "../types.h"
+#include "checking_mutex.h"
-static_assert(!std::is_copy_constructible<std::lock_guard<MyMutex> >::value, "");
+static_assert(!std::is_copy_constructible<std::lock_guard<checking_mutex> >::value, "");
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/default.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/default.pass.cpp
index 6fc4f7f23ced3a..f6ca534de42fe9 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/default.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/default.pass.cpp
@@ -14,12 +14,17 @@
#include <cassert>
#include <mutex>
+#include <type_traits>
+#include "checking_mutex.h"
#include "test_macros.h"
-#include "../types.h"
+
+#if TEST_STD_VER >= 11
+static_assert(std::is_nothrow_default_constructible<std::unique_lock<checking_mutex>>::value, "");
+#endif
int main(int, char**) {
- std::unique_lock<MyMutex> ul;
+ std::unique_lock<checking_mutex> ul;
assert(!ul.owns_lock());
assert(ul.mutex() == nullptr);
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_assign.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_assign.pass.cpp
index 9563fdebd3e060..588d8332c4164b 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_assign.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_assign.pass.cpp
@@ -13,37 +13,24 @@
// unique_lock& operator=(unique_lock&& u);
#include <cassert>
+#include <memory>
#include <mutex>
-#include "nasty_containers.h"
-#include "../types.h"
-#include "test_macros.h"
+#include "checking_mutex.h"
int main(int, char**) {
- {
- typedef MyMutex M;
- M m0;
- M m1;
- std::unique_lock<M> lk0(m0);
- std::unique_lock<M> lk1(m1);
- lk1 = std::move(lk0);
- assert(lk1.mutex() == std::addressof(m0));
- assert(lk1.owns_lock() == true);
- assert(lk0.mutex() == nullptr);
- assert(lk0.owns_lock() == false);
- }
- {
- typedef nasty_mutex M;
- M m0;
- M m1;
- std::unique_lock<M> lk0(m0);
- std::unique_lock<M> lk1(m1);
- lk1 = std::move(lk0);
- assert(lk1.mutex() == std::addressof(m0));
- assert(lk1.owns_lock() == true);
- assert(lk0.mutex() == nullptr);
- assert(lk0.owns_lock() == false);
- }
+ checking_mutex m0;
+ checking_mutex m1;
+ std::unique_lock<checking_mutex> lk0(m0);
+ std::unique_lock<checking_mutex> lk1(m1);
+
+ auto& result = (lk1 = std::move(lk0));
+
+ assert(&result == &lk1);
+ assert(lk1.mutex() == std::addressof(m0));
+ assert(lk1.owns_lock());
+ assert(lk0.mutex() == nullptr);
+ assert(!lk0.owns_lock());
return 0;
}
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_ctor.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_ctor.pass.cpp
index 08f6fc8410e25e..7dab92ab69d987 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_ctor.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_ctor.pass.cpp
@@ -5,8 +5,6 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
-//
-// UNSUPPORTED: c++03
// <mutex>
@@ -15,33 +13,26 @@
// unique_lock(unique_lock&& u);
#include <cassert>
+#include <memory>
#include <mutex>
+#include <type_traits>
-#include "nasty_containers.h"
-#include "../types.h"
+#include "checking_mutex.h"
#include "test_macros.h"
+#if TEST_STD_VER >= 11
+static_assert(std::is_nothrow_move_constructible<std::unique_lock<checking_mutex>>::value, "");
+#endif
+
int main(int, char**) {
- {
- typedef MyMutex M;
- M m;
- std::unique_lock<M> lk0(m);
- std::unique_lock<M> lk = std::move(lk0);
- assert(lk.mutex() == std::addressof(m));
- assert(lk.owns_lock() == true);
- assert(lk0.mutex() == nullptr);
- assert(lk0.owns_lock() == false);
- }
- {
- typedef nasty_mutex M;
- M m;
- std::unique_lock<M> lk0(m);
- std::unique_lock<M> lk = std::move(lk0);
- assert(lk.mutex() == std::addressof(m));
- assert(lk.owns_lock() == true);
- assert(lk0.mutex() == nullptr);
- assert(lk0.owns_lock() == false);
- }
+ checking_mutex m;
+ std::unique_lock<checking_mutex> lk0(m);
+ std::unique_lock<checking_mutex> lk = std::move(lk0);
+
+ assert(lk.mutex() == std::addressof(m));
+ assert(lk.owns_lock());
+ assert(lk0.mutex() == nullptr);
+ assert(!lk0.owns_lock());
return 0;
}
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex.pass.cpp
index 2be25748e903b0..31f15deec0cfaf 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex.pass.cpp
@@ -5,9 +5,6 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
-//
-// UNSUPPORTED: no-threads
-// ALLOW_RETRIES: 2
// <mutex>
@@ -19,45 +16,22 @@
// -> unique_lock<_Mutex>; // C++17
#include <cassert>
-#include <chrono>
-#include <cstdlib>
#include <mutex>
-#include <thread>
-#include "make_test_thread.h"
+#include "checking_mutex.h"
#include "test_macros.h"
-std::mutex m;
-
-typedef std::chrono::system_clock Clock;
-typedef Clock::time_point time_point;
-typedef Clock::duration duration;
-typedef std::chrono::milliseconds ms;
-typedef std::chrono::nanoseconds ns;
-
-void f()
-{
- time_point t0 = Clock::now();
- time_point t1;
- {
- std::unique_lock<std::mutex> ul(m);
- t1 = Clock::now();
- }
- ns d = t1 - t0 - ms(250);
- assert(d < ms(50)); // within 50ms
-}
+int main(int, char**) {
+ checking_mutex mux;
-int main(int, char**)
-{
- m.lock();
- std::thread t = support::make_test_thread(f);
- std::this_thread::sleep_for(ms(250));
- m.unlock();
- t.join();
+ {
+ std::unique_lock<checking_mutex> lock(mux);
+ assert(mux.current_state == checking_mutex::locked_via_lock);
+ }
+ assert(mux.current_state == checking_mutex::unlocked);
#if TEST_STD_VER >= 17
- std::unique_lock ul(m);
- static_assert((std::is_same<decltype(ul), std::unique_lock<decltype(m)>>::value), "" );
+ static_assert(std::is_same_v<std::unique_lock<checking_mutex>, decltype(std::unique_lock{mux})>, "");
#endif
return 0;
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_adopt_lock.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_adopt_lock.pass.cpp
index 28cc43853180e6..14db741fa4adc3 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_adopt_lock.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_adopt_lock.pass.cpp
@@ -5,8 +5,6 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
-//
-// UNSUPPORTED: c++03
// <mutex>
@@ -15,29 +13,19 @@
// unique_lock(mutex_type& m, adopt_lock_t);
#include <cassert>
+#include <memory>
#include <mutex>
-#include "nasty_containers.h"
-#include "../types.h"
-#include "test_macros.h"
+#include "checking_mutex.h"
int main(int, char**) {
- {
- typedef MyMutex M;
- M m;
- m.lock();
- std::unique_lock<M> lk(m, std::adopt_lock);
- assert(lk.mutex() == std::addressof(m));
- assert(lk.owns_lock() == true);
- }
- {
- typedef nasty_mutex M;
- M m;
- m.lock();
- std::unique_lock<M> lk(m, std::adopt_lock);
- assert(lk.mutex() == std::addressof(m));
- assert(lk.owns_lock() == true);
- }
+ checking_mutex m;
+ m.lock();
+ m.last_try = checking_mutex::none;
+ std::unique_lock<checking_mutex> lk(m, std::adopt_lock_t());
+ assert(m.last_try == checking_mutex::none);
+ assert(lk.mutex() == std::addressof(m));
+ assert(lk.owns_lock());
return 0;
}
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_defer_lock.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_defer_lock.pass.cpp
index 96a9afbc9438c4..4335892dd28477 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_defer_lock.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_defer_lock.pass.cpp
@@ -5,8 +5,6 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
-//
-// UNSUPPORTED: c++03
// <mutex>
@@ -15,27 +13,24 @@
// unique_lock(mutex_type& m, defer_lock_t);
#include <cassert>
+#include <memory>
#include <mutex>
+#include <type_traits>
-#include "nasty_containers.h"
-#include "../types.h"
+#include "checking_mutex.h"
#include "test_macros.h"
+#if TEST_STD_VER >= 11
+static_assert(
+ std::is_nothrow_constructible<std::unique_lock<checking_mutex>, checking_mutex&, std::defer_lock_t>::value, "");
+#endif
+
int main(int, char**) {
- {
- typedef MyMutex M;
- M m;
- std::unique_lock<M> lk(m, std::defer_lock);
- assert(lk.mutex() == std::addressof(m));
- assert(lk.owns_lock() == false);
- }
- {
- typedef nasty_mutex M;
- M m;
- std::unique_lock<M> lk(m, std::defer_lock);
- assert(lk.mutex() == std::addressof(m));
- assert(lk.owns_lock() == false);
- }
+ checking_mutex m;
+ std::unique_lock<checking_mutex> lk(m, std::defer_lock_t());
+ assert(m.last_try == checking_mutex::none);
+ assert(lk.mutex() == std::addressof(m));
+ assert(lk.owns_lock() == false);
return 0;
}
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_duration.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_duration.pass.cpp
index 4bfabab919f177..624b99623d6be7 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_duration.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_duration.pass.cpp
@@ -5,69 +5,36 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
-//
-// UNSUPPORTED: no-threads
-// ALLOW_RETRIES: 2
// <mutex>
-// class timed_mutex;
-
// template <class Rep, class Period>
-// unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
+// unique_lock::unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
-#include <mutex>
-#include <thread>
-#include <cstdlib>
#include <cassert>
+#include <chrono>
+#include <mutex>
-#include "make_test_thread.h"
-#include "test_macros.h"
-
-std::timed_mutex m;
-
-typedef std::chrono::steady_clock Clock;
-typedef Clock::time_point time_point;
-typedef Clock::duration duration;
-typedef std::chrono::milliseconds ms;
-typedef std::chrono::nanoseconds ns;
-
-void f1()
-{
- time_point t0 = Clock::now();
- std::unique_lock<std::timed_mutex> lk(m, ms(300));
- assert(lk.owns_lock() == true);
- time_point t1 = Clock::now();
- ns d = t1 - t0 - ms(250);
- assert(d < ms(50)); // within 50ms
-}
-
-void f2()
-{
- time_point t0 = Clock::now();
- std::unique_lock<std::timed_mutex> lk(m, ms(250));
- assert(lk.owns_lock() == false);
- time_point t1 = Clock::now();
- ns d = t1 - t0 - ms(250);
- assert(d < ms(50)); // within 50ms
-}
-
-int main(int, char**)
-{
- {
- m.lock();
- std::thread t = support::make_test_thread(f1);
- std::this_thread::sleep_for(ms(250));
- m.unlock();
- t.join();
- }
- {
- m.lock();
- std::thread t = support::make_test_thread(f2);
- std::this_thread::sleep_for(ms(300));
- m.unlock();
- t.join();
- }
+#include "checking_mutex.h"
+
+int main(int, char**) {
+ checking_mutex mux;
+ { // check successful lock
+ mux.reject = false;
+ std::unique_lock<checking_mutex> lock(mux, std::chrono::seconds());
+ assert(mux.current_state == checking_mutex::locked_via_try_lock_for);
+ assert(lock.owns_lock());
+ }
+ assert(mux.current_state == checking_mutex::unlocked);
+
+ { // check unsuccessful lock
+ mux.reject = true;
+ std::unique_lock<checking_mutex> lock(mux, std::chrono::seconds());
+ assert(mux.current_state == checking_mutex::unlocked);
+ assert(mux.last_try == checking_mutex::locked_via_try_lock_for);
+ assert(!lock.owns_lock());
+ }
+ assert(mux.current_state == checking_mutex::unlocked);
return 0;
}
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_time_point.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_time_point.pass.cpp
index b85bbace3233c1..93d322050476f6 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_time_point.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_time_point.pass.cpp
@@ -5,69 +5,37 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
-//
-// UNSUPPORTED: no-threads
-// ALLOW_RETRIES: 2
// <mutex>
-// class timed_mutex;
-
// template <class Clock, class Duration>
-// unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
+// unique_lock::unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
-#include <mutex>
-#include <thread>
-#include <cstdlib>
#include <cassert>
+#include <chrono>
+#include <mutex>
-#include "make_test_thread.h"
-#include "test_macros.h"
-
-std::timed_mutex m;
-
-typedef std::chrono::steady_clock Clock;
-typedef Clock::time_point time_point;
-typedef Clock::duration duration;
-typedef std::chrono::milliseconds ms;
-typedef std::chrono::nanoseconds ns;
-
-void f1()
-{
- time_point t0 = Clock::now();
- std::unique_lock<std::timed_mutex> lk(m, Clock::now() + ms(300));
- assert(lk.owns_lock() == true);
- time_point t1 = Clock::now();
- ns d = t1 - t0 - ms(250);
- assert(d < ns(50000000)); // within 50ms
-}
-
-void f2()
-{
- time_point t0 = Clock::now();
- std::unique_lock<std::timed_mutex> lk(m, Clock::now() + ms(250));
- assert(lk.owns_lock() == false);
- time_point t1 = Clock::now();
- ns d = t1 - t0 - ms(250);
- assert(d < ms(50)); // within 50ms
-}
-
-int main(int, char**)
-{
- {
- m.lock();
- std::thread t = support::make_test_thread(f1);
- std::this_thread::sleep_for(ms(250));
- m.unlock();
- t.join();
- }
- {
- m.lock();
- std::thread t = support::make_test_thread(f2);
- std::this_thread::sleep_for(ms(300));
- m.unlock();
- t.join();
- }
+#include "checking_mutex.h"
+
+int main(int, char**) {
+ checking_mutex mux;
+
+ { // check successful lock
+ mux.reject = false;
+ std::unique_lock<checking_mutex> lock(mux, std::chrono::time_point<std::chrono::system_clock>());
+ assert(mux.current_state == checking_mutex::locked_via_try_lock_until);
+ assert(lock.owns_lock());
+ }
+ assert(mux.current_state == checking_mutex::unlocked);
+
+ { // check unsuccessful lock
+ mux.reject = true;
+ std::unique_lock<checking_mutex> lock(mux, std::chrono::time_point<std::chrono::system_clock>());
+ assert(mux.current_state == checking_mutex::unlocked);
+ assert(mux.last_try == checking_mutex::locked_via_try_lock_until);
+ assert(!lock.owns_lock());
+ }
+ assert(mux.current_state == checking_mutex::unlocked);
return 0;
}
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_try_to_lock.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_try_to_lock.pass.cpp
index 992d383dfa780d..e7af0fc34e7509 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_try_to_lock.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_try_to_lock.pass.cpp
@@ -6,10 +6,6 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: no-threads
-// UNSUPPORTED: c++03
-// ALLOW_RETRIES: 2
-
// <mutex>
// template <class Mutex> class unique_lock;
@@ -17,55 +13,29 @@
// unique_lock(mutex_type& m, try_to_lock_t);
#include <cassert>
-#include <chrono>
-#include <cstdlib>
#include <mutex>
-#include <thread>
-
-#include "make_test_thread.h"
-#include "test_macros.h"
-
-std::mutex m;
-
-typedef std::chrono::system_clock Clock;
-typedef Clock::time_point time_point;
-typedef Clock::duration duration;
-typedef std::chrono::milliseconds ms;
-typedef std::chrono::nanoseconds ns;
-
-void f()
-{
- time_point t0 = Clock::now();
- {
- std::unique_lock<std::mutex> lk(m, std::try_to_lock);
- assert(lk.owns_lock() == false);
- }
- {
- std::unique_lock<std::mutex> lk(m, std::try_to_lock);
- assert(lk.owns_lock() == false);
- }
- {
- std::unique_lock<std::mutex> lk(m, std::try_to_lock);
- assert(lk.owns_lock() == false);
- }
- while (true)
- {
- std::unique_lock<std::mutex> lk(m, std::try_to_lock);
- if (lk.owns_lock())
- break;
- }
- time_point t1 = Clock::now();
- ns d = t1 - t0 - ms(250);
- assert(d < ms(200)); // within 200ms
-}
-int main(int, char**)
-{
- m.lock();
- std::thread t = support::make_test_thread(f);
- std::this_thread::sleep_for(ms(250));
- m.unlock();
- t.join();
+#include "checking_mutex.h"
+
+int main(int, char**) {
+ checking_mutex mux;
+
+ { // check successful lock
+ mux.reject = false;
+ std::unique_lock<checking_mutex> lock(mux, std::try_to_lock_t());
+ assert(mux.current_state == checking_mutex::locked_via_try_lock);
+ assert(lock.owns_lock());
+ }
+ assert(mux.current_state == checking_mutex::unlocked);
+
+ { // check successful lock
+ mux.reject = true;
+ std::unique_lock<checking_mutex> lock(mux, std::try_to_lock_t());
+ assert(mux.last_try == checking_mutex::locked_via_try_lock);
+ assert(mux.current_state == checking_mutex::unlocked);
+ assert(!lock.owns_lock());
+ }
+ assert(mux.current_state == checking_mutex::unlocked);
return 0;
}
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/lock.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/lock.pass.cpp
index 6767e11a1f8b49..4be1eaa5e1b95f 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/lock.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/lock.pass.cpp
@@ -5,10 +5,6 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
-//
-// UNSUPPORTED: no-threads
-// UNSUPPORTED: c++03
-// ALLOW_RETRIES: 2
// <mutex>
@@ -17,65 +13,42 @@
// void lock();
#include <cassert>
-#include <chrono>
-#include <cstdlib>
#include <mutex>
#include <system_error>
-#include <thread>
-#include "make_test_thread.h"
+#include "checking_mutex.h"
#include "test_macros.h"
-std::mutex m;
+int main(int, char**) {
+ checking_mutex mux;
+ std::unique_lock<checking_mutex> lk(mux, std::defer_lock_t());
+ assert(mux.last_try == checking_mutex::none);
+ lk.lock();
+ assert(mux.current_state == checking_mutex::locked_via_lock);
+ mux.last_try = checking_mutex::none;
-typedef std::chrono::system_clock Clock;
-typedef Clock::time_point time_point;
-typedef Clock::duration duration;
-typedef std::chrono::milliseconds ms;
-typedef std::chrono::nanoseconds ns;
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ try {
+ mux.last_try = checking_mutex::none;
+ lk.lock();
+ assert(false);
+ } catch (std::system_error& e) {
+ assert(mux.last_try == checking_mutex::none);
+ assert(e.code() == std::errc::resource_deadlock_would_occur);
+ }
-void f()
-{
- std::unique_lock<std::mutex> lk(m, std::defer_lock);
- time_point t0 = Clock::now();
+ lk.unlock();
+ lk.release();
+
+ try {
+ mux.last_try = checking_mutex::none;
lk.lock();
- time_point t1 = Clock::now();
- assert(lk.owns_lock() == true);
- ns d = t1 - t0 - ms(250);
- assert(d < ms(25)); // within 25ms
-#ifndef TEST_HAS_NO_EXCEPTIONS
- try
- {
- lk.lock();
- assert(false);
- }
- catch (std::system_error& e)
- {
- assert(e.code() == std::errc::resource_deadlock_would_occur);
- }
+ assert(false);
+ } catch (std::system_error& e) {
+ assert(mux.last_try == checking_mutex::none);
+ assert(e.code() == std::errc::operation_not_permitted);
+ }
#endif
- lk.unlock();
- lk.release();
-#ifndef TEST_HAS_NO_EXCEPTIONS
- try
- {
- lk.lock();
- assert(false);
- }
- catch (std::system_error& e)
- {
- assert(e.code() == std::errc::operation_not_permitted);
- }
-#endif
-}
-
-int main(int, char**)
-{
- m.lock();
- std::thread t = support::make_test_thread(f);
- std::this_thread::sleep_for(ms(250));
- m.unlock();
- t.join();
return 0;
}
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 2ee5d3766eb18e..41a5957480556b 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,9 +5,6 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
-//
-// UNSUPPORTED: c++03
-// ALLOW_RETRIES: 2
// <mutex>
@@ -20,33 +17,43 @@
#include <system_error>
#include "test_macros.h"
-#include "../types.h"
-
-MyTimedMutex m;
+#include "checking_mutex.h"
int main(int, char**) {
- std::unique_lock<MyTimedMutex> lk(m, std::defer_lock);
- assert(lk.try_lock() == true);
- assert(m.try_lock_called == true);
- assert(lk.owns_lock() == true);
+ checking_mutex mux;
+
+ std::unique_lock<checking_mutex> lock(mux, std::defer_lock_t());
+ assert(lock.try_lock());
+ assert(mux.current_state == checking_mutex::locked_via_try_lock);
+ assert(lock.owns_lock());
+
#ifndef TEST_HAS_NO_EXCEPTIONS
try {
- TEST_IGNORE_NODISCARD lk.try_lock();
+ mux.last_try = checking_mutex::none;
+ TEST_IGNORE_NODISCARD lock.try_lock();
assert(false);
} catch (std::system_error& e) {
+ assert(mux.last_try == checking_mutex::none);
assert(e.code() == std::errc::resource_deadlock_would_occur);
}
#endif
- lk.unlock();
- assert(lk.try_lock() == false);
- assert(m.try_lock_called == false);
- assert(lk.owns_lock() == false);
- lk.release();
+
+ lock.unlock();
+ mux.reject = true;
+
+ assert(!lock.try_lock());
+ assert(mux.last_try == checking_mutex::locked_via_try_lock);
+
+ assert(!lock.owns_lock());
+ lock.release();
+
#ifndef TEST_HAS_NO_EXCEPTIONS
try {
- TEST_IGNORE_NODISCARD lk.try_lock();
+ mux.last_try = checking_mutex::none;
+ (void)lock.try_lock();
assert(false);
} catch (std::system_error& e) {
+ assert(mux.last_try == checking_mutex::none);
assert(e.code() == std::errc::operation_not_permitted);
}
#endif
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 603cc7b185620c..cfe81a8faf3386 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,6 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
-//
-// UNSUPPORTED: c++03
// <mutex>
@@ -20,34 +18,47 @@
#include <system_error>
#include "test_macros.h"
-#include "../types.h"
-
-MyTimedMutex m;
+#include "checking_mutex.h"
int main(int, char**) {
using ms = std::chrono::milliseconds;
- std::unique_lock<MyTimedMutex> lk(m, std::defer_lock);
- assert(lk.try_lock_for(ms(5)) == true);
- assert(m.try_lock_for_called == true);
- assert(lk.owns_lock() == true);
+
+ checking_mutex mux;
+
+ std::unique_lock<checking_mutex> lock(mux, std::defer_lock_t());
+
+ assert(lock.try_lock_for(ms(5)));
+ assert(mux.current_state == checking_mutex::locked_via_try_lock_for);
+ assert(lock.owns_lock());
+
#ifndef TEST_HAS_NO_EXCEPTIONS
try {
- TEST_IGNORE_NODISCARD lk.try_lock_for(ms(5));
+ mux.last_try = checking_mutex::none;
+ (void)lock.try_lock_for(ms(5));
+
assert(false);
} catch (std::system_error& e) {
+ assert(mux.last_try == checking_mutex::none);
assert(e.code() == std::errc::resource_deadlock_would_occur);
}
#endif
- lk.unlock();
- assert(lk.try_lock_for(ms(5)) == false);
- assert(m.try_lock_for_called == false);
- assert(lk.owns_lock() == false);
- lk.release();
+
+ lock.unlock();
+ mux.reject = true;
+ assert(!lock.try_lock_for(ms(5)));
+ assert(mux.last_try == checking_mutex::locked_via_try_lock_for);
+ assert(!lock.owns_lock());
+
+ lock.release();
+
#ifndef TEST_HAS_NO_EXCEPTIONS
try {
- TEST_IGNORE_NODISCARD lk.try_lock_for(ms(5));
+ mux.last_try = checking_mutex::none;
+ (void)lock.try_lock_for(ms(5));
+
assert(false);
} catch (std::system_error& e) {
+ assert(mux.last_try == checking_mutex::none);
assert(e.code() == std::errc::operation_not_permitted);
}
#endif
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 46ab95197311c0..bc261f681020f3 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,6 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
-//
-// UNSUPPORTED: c++03
// <mutex>
@@ -20,35 +18,44 @@
#include <mutex>
#include <system_error>
+#include "checking_mutex.h"
#include "test_macros.h"
-#include "../types.h"
-
-MyTimedMutex m;
int main(int, char**) {
typedef std::chrono::system_clock Clock;
- std::unique_lock<MyTimedMutex> lk(m, std::defer_lock);
- assert(lk.try_lock_until(Clock::now()) == true);
- assert(m.try_lock_until_called == true);
- assert(lk.owns_lock() == true);
+ checking_mutex mux;
+
+ std::unique_lock<checking_mutex> lock(mux, std::defer_lock_t());
+
+ assert(lock.try_lock_until(Clock::now()));
+ assert(mux.current_state == checking_mutex::locked_via_try_lock_until);
+ assert(lock.owns_lock());
+
#ifndef TEST_HAS_NO_EXCEPTIONS
try {
- TEST_IGNORE_NODISCARD lk.try_lock_until(Clock::now());
+ mux.last_try = checking_mutex::none;
+ (void)lock.try_lock_until(Clock::now());
assert(false);
} catch (std::system_error& e) {
+ assert(mux.last_try == checking_mutex::none);
assert(e.code() == std::errc::resource_deadlock_would_occur);
}
#endif
- lk.unlock();
- assert(lk.try_lock_until(Clock::now()) == false);
- assert(m.try_lock_until_called == false);
- assert(lk.owns_lock() == false);
- lk.release();
+
+ lock.unlock();
+ mux.reject = true;
+ assert(!lock.try_lock_until(Clock::now()));
+ assert(mux.last_try == checking_mutex::locked_via_try_lock_until);
+ assert(lock.owns_lock() == false);
+ lock.release();
+
#ifndef TEST_HAS_NO_EXCEPTIONS
try {
- TEST_IGNORE_NODISCARD lk.try_lock_until(Clock::now());
+ mux.last_try = checking_mutex::none;
+ (void)lock.try_lock_until(Clock::now());
assert(false);
} catch (std::system_error& e) {
+ assert(mux.last_try == checking_mutex::none);
assert(e.code() == std::errc::operation_not_permitted);
}
#endif
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/unlock.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/unlock.pass.cpp
index 97808f60f2e552..cfc44a6cd5d254 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/unlock.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/unlock.pass.cpp
@@ -17,28 +17,36 @@
#include <system_error>
#include "test_macros.h"
-#include "../types.h"
-
-MyMutex m;
+#include "checking_mutex.h"
int main(int, char**) {
- std::unique_lock<MyMutex> lk(m);
- lk.unlock();
- assert(lk.owns_lock() == false);
+ checking_mutex mux;
+ std::unique_lock<checking_mutex> lock(mux);
+ assert(mux.current_state == checking_mutex::locked_via_lock);
+ lock.unlock();
+ assert(mux.current_state == checking_mutex::unlocked);
+ assert(!lock.owns_lock());
+
#ifndef TEST_HAS_NO_EXCEPTIONS
try {
- lk.unlock();
+ mux.last_try = checking_mutex::none;
+ lock.unlock();
assert(false);
} catch (std::system_error& e) {
+ assert(mux.last_try == checking_mutex::none);
assert(e.code() == std::errc::operation_not_permitted);
}
#endif
- lk.release();
+
+ lock.release();
+
#ifndef TEST_HAS_NO_EXCEPTIONS
try {
- lk.unlock();
+ mux.last_try = checking_mutex::none;
+ lock.unlock();
assert(false);
} catch (std::system_error& e) {
+ assert(mux.last_try == checking_mutex::none);
assert(e.code() == std::errc::operation_not_permitted);
}
#endif
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 361c85e0150597..e2ffbf4a23a9c5 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
@@ -13,21 +13,29 @@
// void swap(unique_lock& u);
#include <cassert>
+#include <memory>
#include <mutex>
+#include "checking_mutex.h"
#include "test_macros.h"
-#include "../types.h"
-MyMutex m;
+#if TEST_STD_VER >= 11
+static_assert(
+ noexcept(std::declval<std::unique_lock<checking_mutex>&>().swap(std::declval<std::unique_lock<checking_mutex>&>())),
+ "");
+#endif
int main(int, char**) {
- std::unique_lock<MyMutex> lk1(m);
- std::unique_lock<MyMutex> lk2;
- lk1.swap(lk2);
- assert(lk1.mutex() == nullptr);
- assert(lk1.owns_lock() == false);
- assert(lk2.mutex() == &m);
- assert(lk2.owns_lock() == true);
+ checking_mutex mux;
+ std::unique_lock<checking_mutex> lock1(mux);
+ std::unique_lock<checking_mutex> lock2;
+
+ lock1.swap(lock2);
+
+ assert(lock1.mutex() == nullptr);
+ assert(!lock1.owns_lock());
+ assert(lock2.mutex() == std::addressof(mux));
+ assert(lock2.owns_lock() == true);
return 0;
}
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 5133032f6ae39e..3e89e6c66bf3e0 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
@@ -14,21 +14,29 @@
// void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y);
#include <cassert>
+#include <memory>
#include <mutex>
+#include "checking_mutex.h"
#include "test_macros.h"
-#include "../types.h"
-MyMutex m;
+#if TEST_STD_VER >= 11
+static_assert(noexcept(swap(std::declval<std::unique_lock<checking_mutex>&>(),
+ std::declval<std::unique_lock<checking_mutex>&>())),
+ "");
+#endif
int main(int, char**) {
- std::unique_lock<MyMutex> lk1(m);
- std::unique_lock<MyMutex> lk2;
- swap(lk1, lk2);
- assert(lk1.mutex() == nullptr);
- assert(lk1.owns_lock() == false);
- assert(lk2.mutex() == &m);
- assert(lk2.owns_lock() == true);
+ checking_mutex mux;
+ std::unique_lock<checking_mutex> lock1(mux);
+ std::unique_lock<checking_mutex> lock2;
+
+ swap(lock1, lock2);
+
+ assert(lock1.mutex() == nullptr);
+ assert(!lock1.owns_lock());
+ assert(lock2.mutex() == std::addressof(mux));
+ assert(lock2.owns_lock() == true);
return 0;
}
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 a726c8ccc060a1..5f972561ecdb8c 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
@@ -13,27 +13,30 @@
// mutex_type* release() noexcept;
#include <cassert>
+#include <memory>
#include <mutex>
+#include "checking_mutex.h"
#include "test_macros.h"
-#include "../types.h"
-int MyCountingMutex::lock_count = 0;
-int MyCountingMutex::unlock_count = 0;
-
-MyCountingMutex m;
+#if TEST_STD_VER >= 11
+static_assert(noexcept(std::declval<std::unique_lock<checking_mutex>&>().release()));
+#endif
int main(int, char**) {
- std::unique_lock<MyCountingMutex> lk(m);
- assert(lk.mutex() == &m);
- assert(lk.owns_lock() == true);
- assert(MyCountingMutex::lock_count == 1);
- assert(MyCountingMutex::unlock_count == 0);
- assert(lk.release() == &m);
- assert(lk.mutex() == nullptr);
- assert(lk.owns_lock() == false);
- assert(MyCountingMutex::lock_count == 1);
- assert(MyCountingMutex::unlock_count == 0);
+ checking_mutex mux;
+ std::unique_lock<checking_mutex> lock(mux);
+ assert(lock.mutex() == std::addressof(mux));
+ assert(lock.owns_lock());
+
+ assert(mux.current_state == checking_mutex::locked_via_lock);
+
+ assert(lock.release() == std::addressof(mux));
+ assert(lock.mutex() == nullptr);
+ assert(!lock.owns_lock());
+ assert(mux.last_try == checking_mutex::locked_via_lock);
+ assert(mux.current_state == checking_mutex::locked_via_lock);
+ mux.unlock();
return 0;
}
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/mutex.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/mutex.pass.cpp
index 72346e8c67e257..f00614015bbc3b 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/mutex.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/mutex.pass.cpp
@@ -13,20 +13,25 @@
// mutex_type *mutex() const;
#include <cassert>
+#include <memory>
#include <mutex>
+#include "checking_mutex.h"
#include "test_macros.h"
-#include "../types.h"
-MyMutex m;
+#if TEST_STD_VER >= 11
+static_assert(noexcept(std::declval<std::unique_lock<checking_mutex>&>().mutex()), "");
+#endif
int main(int, char**) {
- std::unique_lock<MyMutex> lk0;
- assert(lk0.mutex() == nullptr);
- std::unique_lock<MyMutex> lk1(m);
- assert(lk1.mutex() == &m);
- lk1.unlock();
- assert(lk1.mutex() == &m);
+ checking_mutex mux;
+ const std::unique_lock<checking_mutex> lock0; // Make sure `mutex()` is `const`
+ static_assert(std::is_same<decltype(lock0.mutex()), checking_mutex*>::value, "");
+ assert(lock0.mutex() == nullptr);
+ std::unique_lock<checking_mutex> lock1(mux);
+ assert(lock1.mutex() == std::addressof(mux));
+ lock1.unlock();
+ assert(lock1.mutex() == std::addressof(mux));
return 0;
}
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/op_bool.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/op_bool.pass.cpp
index 3759302a483eb2..3542a40d25d39e 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/op_bool.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/op_bool.pass.cpp
@@ -16,21 +16,25 @@
#include <mutex>
#include <type_traits>
+#include "checking_mutex.h"
#include "test_macros.h"
-#include "../types.h"
-MyMutex m;
+#if TEST_STD_VER >= 11
+static_assert(noexcept(static_cast<bool>(std::declval<std::unique_lock<checking_mutex>&>())), "");
+#endif
int main(int, char**) {
- static_assert(std::is_constructible<bool, std::unique_lock<MyMutex> >::value, "");
- static_assert(!std::is_convertible<std::unique_lock<MyMutex>, bool>::value, "");
-
- std::unique_lock<MyMutex> lk0;
- assert(static_cast<bool>(lk0) == false);
- std::unique_lock<MyMutex> lk1(m);
- assert(static_cast<bool>(lk1) == true);
+ static_assert(std::is_constructible<bool, std::unique_lock<checking_mutex> >::value, "");
+ static_assert(!std::is_convertible<std::unique_lock<checking_mutex>, bool>::value, "");
+
+ checking_mutex mux;
+ const std::unique_lock<checking_mutex> lk0; // Make sure `operator bool()` is `const`
+ assert(!static_cast<bool>(lk0));
+ std::unique_lock<checking_mutex> lk1(mux);
+ assert(static_cast<bool>(lk1));
lk1.unlock();
- assert(static_cast<bool>(lk1) == false);
+ assert(!static_cast<bool>(lk1));
+
ASSERT_NOEXCEPT(static_cast<bool>(lk0));
return 0;
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/owns_lock.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/owns_lock.pass.cpp
index 163942786323af..11a674a55392fe 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/owns_lock.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/owns_lock.pass.cpp
@@ -15,18 +15,23 @@
#include <cassert>
#include <mutex>
+#include "checking_mutex.h"
#include "test_macros.h"
-#include "../types.h"
-MyMutex m;
+#if TEST_STD_VER >= 11
+static_assert(noexcept(std::declval<std::unique_lock<checking_mutex>&>().owns_lock()), "");
+#endif
int main(int, char**) {
- std::unique_lock<MyMutex> lk0;
- assert(lk0.owns_lock() == false);
- std::unique_lock<MyMutex> lk1(m);
- assert(lk1.owns_lock() == true);
- lk1.unlock();
- assert(lk1.owns_lock() == false);
+ {
+ checking_mutex mux;
+ const std::unique_lock<checking_mutex> lock0; // Make sure `owns_lock()` is `const`
+ assert(!lock0.owns_lock());
+ std::unique_lock<checking_mutex> lock1(mux);
+ assert(lock1.owns_lock());
+ lock1.unlock();
+ assert(!lock1.owns_lock());
+ }
return 0;
}
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/types.compile.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/types.compile.pass.cpp
index 312863ae8e743a..56055788965d53 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/types.compile.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/types.compile.pass.cpp
@@ -19,7 +19,6 @@
#include <mutex>
#include <type_traits>
-#include "test_macros.h"
-#include "types.h"
+#include "checking_mutex.h"
-static_assert((std::is_same<std::unique_lock<MyMutex>::mutex_type, MyMutex>::value), "");
+static_assert(std::is_same<std::unique_lock<checking_mutex>::mutex_type, checking_mutex>::value, "");
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/types.h b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/types.h
deleted file mode 100644
index 15a1a531487f50..00000000000000
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/types.h
+++ /dev/null
@@ -1,88 +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
-//
-//===----------------------------------------------------------------------===//
-
-#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>
-#include <chrono>
-
-struct MyMutex {
- bool locked = false;
-
- MyMutex() = default;
- ~MyMutex() { assert(!locked); }
-
- void lock() {
- assert(!locked);
- locked = true;
- }
-
- void unlock() {
- assert(locked);
- locked = false;
- }
-
- bool try_lock() {
- if (locked)
- return false;
- lock();
- return true;
- }
-
- template <class Rep, class Period>
- bool try_lock_for(const std::chrono::duration<Rep, Period>& rel_time) {
- using ms = std::chrono::milliseconds;
- assert(rel_time == ms(5));
- if (locked)
- return false;
- lock();
- return true;
- }
-
- MyMutex(MyMutex const&) = delete;
- MyMutex& operator=(MyMutex const&) = delete;
-};
-
-struct MyTimedMutex {
- using ms = std::chrono::milliseconds;
-
- bool try_lock_called = false;
- bool try_lock_for_called = false;
- bool try_lock_until_called = false;
-
- bool try_lock() {
- try_lock_called = !try_lock_called;
- return try_lock_called;
- }
-
- template <class Rep, class Period>
- bool try_lock_for(const std::chrono::duration<Rep, Period>& rel_time) {
- assert(rel_time == ms(5));
- try_lock_for_called = !try_lock_for_called;
- return try_lock_for_called;
- }
-
- template <class Clock, class Duration>
- bool try_lock_until(const std::chrono::time_point<Clock, Duration>& abs_time) {
- assert(Clock::now() - abs_time < ms(5));
- try_lock_until_called = !try_lock_until_called;
- return try_lock_until_called;
- }
-
- void unlock() {}
-};
-
-struct MyCountingMutex {
- static int lock_count;
- static int unlock_count;
- void lock() { ++lock_count; }
- void unlock() { ++unlock_count; }
-};
-
-#endif // TEST_STD_THREAD_THREAD_MUTEX_THREAD_LOCK_THREAD_LOCK_GUARD_TYPES_H
diff --git a/libcxx/test/support/checking_mutex.h b/libcxx/test/support/checking_mutex.h
new file mode 100644
index 00000000000000..1a635c32f29a6b
--- /dev/null
+++ b/libcxx/test/support/checking_mutex.h
@@ -0,0 +1,80 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_SUPPORT_CHECKING_MUTEX_H
+#define TEST_SUPPORT_CHECKING_MUTEX_H
+
+#include <cassert>
+#include <chrono>
+
+struct checking_mutex {
+ enum state {
+ locked_via_lock,
+ locked_via_try_lock,
+ locked_via_try_lock_for,
+ locked_via_try_lock_until,
+ unlocked,
+ none,
+ };
+
+ state current_state = unlocked;
+ state last_try = none;
+ bool reject = false;
+
+ checking_mutex() = default;
+ checking_mutex(const checking_mutex&) = delete;
+ ~checking_mutex() { assert(current_state == unlocked); }
+
+ void lock() {
+ assert(current_state == unlocked);
+ assert(!reject);
+ current_state = locked_via_lock;
+ last_try = locked_via_lock;
+ reject = true;
+ }
+
+ void unlock() {
+ assert(current_state != unlocked && current_state != none);
+ last_try = unlocked;
+ current_state = unlocked;
+ reject = false;
+ }
+
+ bool try_lock() {
+ last_try = locked_via_try_lock;
+ if (reject)
+ return false;
+ current_state = locked_via_try_lock;
+ return true;
+ }
+
+ template <class Rep, class Period>
+ bool try_lock_for(const std::chrono::duration<Rep, Period>&) {
+ last_try = locked_via_try_lock_for;
+ if (reject)
+ return false;
+ current_state = locked_via_try_lock_for;
+ return true;
+ }
+
+ template <class Clock, class Duration>
+ bool try_lock_until(const std::chrono::time_point<Clock, Duration>&) {
+ last_try = locked_via_try_lock_until;
+ if (reject)
+ return false;
+ current_state = locked_via_try_lock_until;
+ return true;
+ }
+
+ checking_mutex* operator&() = delete;
+
+ template <class T>
+ void operator,(const T&) = delete;
+};
+
+#endif // TEST_SUPPORT_CHECKING_MUTEX_H
More information about the libcxx-commits
mailing list