diff --git a/libcxx/test/libcxx/atomics/atomics.syn/wait.pass.cpp b/libcxx/test/libcxx/atomics/atomics.syn/wait.issue_85107.pass.cpp similarity index 57% rename from libcxx/test/libcxx/atomics/atomics.syn/wait.pass.cpp rename to libcxx/test/libcxx/atomics/atomics.syn/wait.issue_85107.pass.cpp index 6ae1c0997aad7..03eaa0e55ac6a 100644 --- a/libcxx/test/libcxx/atomics/atomics.syn/wait.pass.cpp +++ b/libcxx/test/libcxx/atomics/atomics.syn/wait.issue_85107.pass.cpp @@ -15,22 +15,40 @@ // XFAIL: availability-synchronization_library-missing +// This is a regression test for https://github.com/llvm/llvm-project/issues/85107, which describes +// how we were using UL_COMPARE_AND_WAIT instead of UL_COMPARE_AND_WAIT64 in the implementation of +// atomic::wait, leading to potential infinite hangs. + #include #include +#include + +#include "make_test_thread.h" -void test_85107() { +int main(int, char**) { if constexpr (sizeof(std::__cxx_contention_t) == 8 && sizeof(long) > 4) { + std::atomic done = false; + auto const timeout = std::chrono::system_clock::now() + std::chrono::seconds(600); // fail after 10 minutes + + auto timeout_thread = support::make_test_thread([&] { + while (!done) { + assert(std::chrono::system_clock::now() < timeout); // make sure we don't hang forever + } + }); + // https://github.com/llvm/llvm-project/issues/85107 // [libc++] atomic_wait uses UL_COMPARE_AND_WAIT when it should use UL_COMPARE_AND_WAIT64 on Darwin constexpr std::__cxx_contention_t old_val = 0; constexpr std::__cxx_contention_t new_val = old_val + (1ll << 32); std::__cxx_atomic_contention_t ct(new_val); - std::__libcpp_atomic_wait(&ct, old_val); // this will hang forever if the bug is present - } -} -int main(int, char**) { - test_85107(); + // This would hang forever if the bug is present, but the test will fail in a bounded amount of + // time due to the timeout above. + std::__libcpp_atomic_wait(&ct, old_val); + + done = true; + timeout_thread.join(); + } return 0; }