https://gcc.gnu.org/g:87c994095b17892922bfcd3c154c51526ece2260

commit r16-4428-g87c994095b17892922bfcd3c154c51526ece2260
Author: Mike Crowe <[email protected]>
Date:   Sun Sep 14 21:21:30 2025 +0100

    libstdc++: Add std::condition_variable tests for negative timeouts 
[PR116586]
    
    Add tests to show that std::condition_variable::wait_until and
    std::condition_variable::wait_for correctly handle negative timeouts.
    
    libstdc++-v3/ChangeLog:
    
            PR libstdc++/116586
            * testsuite/30_threads/condition_variable/members/116586.cc: New
            test.
    
    Signed-off-by: Mike Crowe <[email protected]>

Diff:
---
 .../condition_variable/members/116586.cc           | 60 ++++++++++++++++++++++
 1 file changed, 60 insertions(+)

diff --git 
a/libstdc++-v3/testsuite/30_threads/condition_variable/members/116586.cc 
b/libstdc++-v3/testsuite/30_threads/condition_variable/members/116586.cc
new file mode 100644
index 000000000000..71140078d418
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/condition_variable/members/116586.cc
@@ -0,0 +1,60 @@
+// { dg-do run { target c++11 } }
+
+#include <condition_variable>
+#include <chrono>
+#include <mutex>
+#include <initializer_list>
+#include <testsuite_hooks.h>
+
+namespace chrono = std::chrono;
+
+// thread.timedmutex.requirements.general:
+//   If abs_time has already passed, the function attempts to obtain
+//   ownership without blocking (as if by calling try_lock()).
+
+template <typename Clock>
+void
+test_absolute(chrono::nanoseconds offset)
+{
+  std::mutex mtx;
+  std::condition_variable cv;
+  chrono::time_point<Clock> tp(offset);
+  std::unique_lock<std::mutex> lock(mtx);
+  // Doesn't cope with spurious wakeup
+  VERIFY(cv.wait_until(lock, tp) == std::cv_status::timeout);
+}
+
+// The type of clock used for the actual wait depends on whether
+// _GLIBCXX_USE_PTHREAD_MUTEX_CLOCKLOCK is defined. We might as well just test
+// both steady_clock and system_clock.
+template <typename Clock>
+void
+test_relative(chrono::nanoseconds offset)
+{
+  std::mutex mtx;
+  std::condition_variable cv;
+  const auto d = -Clock::now().time_since_epoch() + offset;
+  std::unique_lock<std::mutex> lock(mtx);
+  // Doesn't cope with spurious wakeup
+  VERIFY(cv.wait_for(lock, d) == std::cv_status::timeout);
+}
+
+int main()
+{
+  // It's not really possible to arrange for the relative calls to have
+  // tv_nsec == 0 due to time advancing.
+  for (const chrono::nanoseconds offset : {
+      // tv_sec == 0, tv_nsec == 0
+      chrono::nanoseconds{0},
+      // tv_sec == 0, tv_nsec < 0
+      chrono::duration_cast<chrono::nanoseconds>(chrono::milliseconds{-10}),
+      // tv_sec < 0
+      chrono::duration_cast<chrono::nanoseconds>(chrono::seconds{-10})
+    }) {
+    test_absolute<chrono::system_clock>(offset);
+    test_relative<chrono::system_clock>(offset);
+
+    test_absolute<chrono::steady_clock>(offset);
+    test_relative<chrono::steady_clock>(offset);
+  }
+}

Reply via email to