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 8c7ca4279eead..cc94c5704327f 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 -#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); - } - - return 0; -} +checking_mutex mux; +static_assert(std::is_same_v, 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 0000000000000..fec8740fbf440 --- /dev/null +++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/mutex.pass.cpp @@ -0,0 +1,69 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// Make sure std::unique_lock works with std::mutex as expected. + +#include +#include +#include + +#include "make_test_thread.h" + +std::atomic keep_waiting; +std::atomic child_thread_locked; +std::mutex mux; +bool main_thread_unlocked = false; +bool child_thread_unlocked = false; + +void lock_thread() { + std::unique_lock lock(mux); + assert(main_thread_unlocked); + main_thread_unlocked = false; + child_thread_unlocked = true; +} + +void try_lock_thread() { + std::unique_lock 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; + child_thread_locked = 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 9ab8369637cdc..c0cb7d4ddd27a 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 -#include "../types.h" +#include "checking_mutex.h" -static_assert(!std::is_copy_assignable >::value, ""); +static_assert(!std::is_copy_assignable >::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 e846061f5fbd0..2846b24125e78 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 -#include "../types.h" +#include "checking_mutex.h" -static_assert(!std::is_copy_constructible >::value, ""); +static_assert(!std::is_copy_constructible >::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 6fc4f7f23ced3..f6ca534de42fe 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 #include +#include +#include "checking_mutex.h" #include "test_macros.h" -#include "../types.h" + +#if TEST_STD_VER >= 11 +static_assert(std::is_nothrow_default_constructible>::value, ""); +#endif int main(int, char**) { - std::unique_lock ul; + std::unique_lock 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 9563fdebd3e06..588d8332c4164 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 +#include #include -#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 lk0(m0); - std::unique_lock 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 lk0(m0); - std::unique_lock 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 lk0(m0); + std::unique_lock 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 08f6fc8410e25..7dab92ab69d98 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 // @@ -15,33 +13,26 @@ // unique_lock(unique_lock&& u); #include +#include #include +#include -#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>::value, ""); +#endif + int main(int, char**) { - { - typedef MyMutex M; - M m; - std::unique_lock lk0(m); - std::unique_lock 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 lk0(m); - std::unique_lock 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 lk0(m); + std::unique_lock 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 2be25748e903b..31f15deec0cfa 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 // @@ -19,45 +16,22 @@ // -> unique_lock<_Mutex>; // C++17 #include -#include -#include #include -#include -#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 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 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>::value), "" ); + static_assert(std::is_same_v, 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 28cc43853180e..14db741fa4adc 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 // @@ -15,29 +13,19 @@ // unique_lock(mutex_type& m, adopt_lock_t); #include +#include #include -#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 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 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 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 96a9afbc9438c..4335892dd2847 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 // @@ -15,27 +13,24 @@ // unique_lock(mutex_type& m, defer_lock_t); #include +#include #include +#include -#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, checking_mutex&, std::defer_lock_t>::value, ""); +#endif + int main(int, char**) { - { - typedef MyMutex M; - M m; - std::unique_lock 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 lk(m, std::defer_lock); - assert(lk.mutex() == std::addressof(m)); - assert(lk.owns_lock() == false); - } + checking_mutex m; + std::unique_lock 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 4bfabab919f17..624b99623d6be 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 // -// class timed_mutex; - // template -// unique_lock(mutex_type& m, const chrono::duration& rel_time); +// unique_lock::unique_lock(mutex_type& m, const chrono::duration& rel_time); -#include -#include -#include #include +#include +#include -#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 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 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 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 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 b85bbace3233c..93d322050476f 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 // -// class timed_mutex; - // template -// unique_lock(mutex_type& m, const chrono::time_point& abs_time); +// unique_lock::unique_lock(mutex_type& m, const chrono::time_point& abs_time); -#include -#include -#include #include +#include +#include -#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 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 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 lock(mux, std::chrono::time_point()); + 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 lock(mux, std::chrono::time_point()); + 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 992d383dfa780..e7af0fc34e750 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 - // // template class unique_lock; @@ -17,55 +13,29 @@ // unique_lock(mutex_type& m, try_to_lock_t); #include -#include -#include #include -#include - -#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 lk(m, std::try_to_lock); - assert(lk.owns_lock() == false); - } - { - std::unique_lock lk(m, std::try_to_lock); - assert(lk.owns_lock() == false); - } - { - std::unique_lock lk(m, std::try_to_lock); - assert(lk.owns_lock() == false); - } - while (true) - { - std::unique_lock 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 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 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 6767e11a1f8b4..4be1eaa5e1b95 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 // @@ -17,65 +13,42 @@ // void lock(); #include -#include -#include #include #include -#include -#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 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 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 2ee5d3766eb18..41a5957480556 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 // @@ -20,33 +17,43 @@ #include #include "test_macros.h" -#include "../types.h" - -MyTimedMutex m; +#include "checking_mutex.h" int main(int, char**) { - std::unique_lock 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 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 603cc7b185620..cfe81a8faf338 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 // @@ -20,34 +18,47 @@ #include #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 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 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 46ab95197311c..bc261f681020f 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 // @@ -20,35 +18,44 @@ #include #include +#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 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 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 97808f60f2e55..cfc44a6cd5d25 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 #include "test_macros.h" -#include "../types.h" - -MyMutex m; +#include "checking_mutex.h" int main(int, char**) { - std::unique_lock lk(m); - lk.unlock(); - assert(lk.owns_lock() == false); + checking_mutex mux; + std::unique_lock 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 361c85e015059..e2ffbf4a23a9c 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 +#include #include +#include "checking_mutex.h" #include "test_macros.h" -#include "../types.h" -MyMutex m; +#if TEST_STD_VER >= 11 +static_assert( + noexcept(std::declval&>().swap(std::declval&>())), + ""); +#endif int main(int, char**) { - std::unique_lock lk1(m); - std::unique_lock 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 lock1(mux); + std::unique_lock 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 5133032f6ae39..3e89e6c66bf3e 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& x, unique_lock& y); #include +#include #include +#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::declval&>())), + ""); +#endif int main(int, char**) { - std::unique_lock lk1(m); - std::unique_lock 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 lock1(mux); + std::unique_lock 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 a726c8ccc060a..a7724504a667c 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 +#include #include +#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&>().release()), ""); +#endif int main(int, char**) { - std::unique_lock 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 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 72346e8c67e25..f00614015bbc3 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 +#include #include +#include "checking_mutex.h" #include "test_macros.h" -#include "../types.h" -MyMutex m; +#if TEST_STD_VER >= 11 +static_assert(noexcept(std::declval&>().mutex()), ""); +#endif int main(int, char**) { - std::unique_lock lk0; - assert(lk0.mutex() == nullptr); - std::unique_lock lk1(m); - assert(lk1.mutex() == &m); - lk1.unlock(); - assert(lk1.mutex() == &m); + checking_mutex mux; + const std::unique_lock lock0; // Make sure `mutex()` is `const` + static_assert(std::is_same::value, ""); + assert(lock0.mutex() == nullptr); + std::unique_lock 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 3759302a483eb..3542a40d25d39 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 #include +#include "checking_mutex.h" #include "test_macros.h" -#include "../types.h" -MyMutex m; +#if TEST_STD_VER >= 11 +static_assert(noexcept(static_cast(std::declval&>())), ""); +#endif int main(int, char**) { - static_assert(std::is_constructible >::value, ""); - static_assert(!std::is_convertible, bool>::value, ""); - - std::unique_lock lk0; - assert(static_cast(lk0) == false); - std::unique_lock lk1(m); - assert(static_cast(lk1) == true); + static_assert(std::is_constructible >::value, ""); + static_assert(!std::is_convertible, bool>::value, ""); + + checking_mutex mux; + const std::unique_lock lk0; // Make sure `operator bool()` is `const` + assert(!static_cast(lk0)); + std::unique_lock lk1(mux); + assert(static_cast(lk1)); lk1.unlock(); - assert(static_cast(lk1) == false); + assert(!static_cast(lk1)); + ASSERT_NOEXCEPT(static_cast(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 163942786323a..11a674a55392f 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 #include +#include "checking_mutex.h" #include "test_macros.h" -#include "../types.h" -MyMutex m; +#if TEST_STD_VER >= 11 +static_assert(noexcept(std::declval&>().owns_lock()), ""); +#endif int main(int, char**) { - std::unique_lock lk0; - assert(lk0.owns_lock() == false); - std::unique_lock lk1(m); - assert(lk1.owns_lock() == true); - lk1.unlock(); - assert(lk1.owns_lock() == false); + { + checking_mutex mux; + const std::unique_lock lock0; // Make sure `owns_lock()` is `const` + assert(!lock0.owns_lock()); + std::unique_lock 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 312863ae8e743..56055788965d5 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 #include -#include "test_macros.h" -#include "types.h" +#include "checking_mutex.h" -static_assert((std::is_same::mutex_type, MyMutex>::value), ""); +static_assert(std::is_same::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 15a1a531487f5..0000000000000 --- 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 -#include - -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 - bool try_lock_for(const std::chrono::duration& 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 - bool try_lock_for(const std::chrono::duration& rel_time) { - assert(rel_time == ms(5)); - try_lock_for_called = !try_lock_for_called; - return try_lock_for_called; - } - - template - bool try_lock_until(const std::chrono::time_point& 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 0000000000000..1a635c32f29a6 --- /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 +#include + +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 + bool try_lock_for(const std::chrono::duration&) { + last_try = locked_via_try_lock_for; + if (reject) + return false; + current_state = locked_via_try_lock_for; + return true; + } + + template + bool try_lock_until(const std::chrono::time_point&) { + 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 + void operator,(const T&) = delete; +}; + +#endif // TEST_SUPPORT_CHECKING_MUTEX_H