[libcxx-commits] [libcxx] [libc++] Make sure the test for compare-and-wait bug doesn't hang forever (PR #97907)

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Sat Jul 6 11:30:11 PDT 2024


https://github.com/ldionne created https://github.com/llvm/llvm-project/pull/97907

This patch adds an explicit timeout mechanism in the compare-and-wait test for std::atomic, ensuring that it doesn't run forever when the bug is present. This is not an issue when we run inside the CI because we specify a timeout manually, but it can be a problem when running locally, for example.

>From fdca2227546f6ead5732b5b463c96425cd6f6ea3 Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Sat, 6 Jul 2024 14:28:39 -0400
Subject: [PATCH] [libc++] Make sure the test for compare-and-wait bug doesn't
 hang forever

This patch adds an explicit timeout mechanism in the compare-and-wait
test for std::atomic, ensuring that it doesn't run forever when the
bug is present. This is not an issue when we run inside the CI because
we specify a timeout manually, but it can be a problem when running
locally, for example.
---
 ...ait.pass.cpp => wait.issue_85107.pass.cpp} | 30 +++++++++++++++----
 1 file changed, 24 insertions(+), 6 deletions(-)
 rename libcxx/test/libcxx/atomics/atomics.syn/{wait.pass.cpp => wait.issue_85107.pass.cpp} (57%)

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 6ae1c0997aad72..03eaa0e55ac6a8 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 <atomic>
 #include <cassert>
+#include <chrono>
+
+#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<bool> 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;
 }



More information about the libcxx-commits mailing list