]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstdc++: Add std::binary_semaphore tests for negative timeouts [PR116586]
authorMike Crowe <mac@mcrowe.com>
Sun, 14 Sep 2025 20:21:28 +0000 (21:21 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Tue, 14 Oct 2025 16:26:43 +0000 (17:26 +0100)
Add test cases to prove that negative timeouts are correctly handled by
std::binary_semaphore (which is just an alias for
std::counting_semaphore<1>).  The tests exercise cases that aren't
problematic with the current code since system_clock is converted to
steady_clock before calling __platform_wait_until() is called but they
will protect against changes in the implementation reintroducing this
bug.

libstdc++-v3/ChangeLog:

PR libstdc++/116586
* testsuite/30_threads/semaphore/try_acquire_for.cc: Add tests.
* testsuite/30_threads/semaphore/try_acquire_until.cc: Add
tests.

Signed-off-by: Mike Crowe <mac@mcrowe.com>
libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_for.cc
libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_until.cc

index 39681c7ee56b7df3d6001b90eb1df1d5faf4c415..94acb253091e768ba3a0aec81b0308b623e6e10e 100644 (file)
@@ -24,6 +24,7 @@
 #include <chrono>
 #include <thread>
 #include <atomic>
+#include <initializer_list>
 #include <testsuite_hooks.h>
 
 void test01()
@@ -90,9 +91,30 @@ test03()
   s.try_acquire_for(timeout);
 }
 
+// Prove semaphore doesn't suffer from PR116586
+template <typename Clock>
+void
+test_relative(std::chrono::nanoseconds offset)
+{
+  std::binary_semaphore sem(1);
+  VERIFY(sem.try_acquire_for(offset));
+  VERIFY(!sem.try_acquire_for(offset));
+}
+
 int main()
 {
   test01();
   test02();
   test03();
+  using namespace std::chrono;
+  for (const nanoseconds offset : {
+      nanoseconds{0},
+      nanoseconds{-10ms},
+      nanoseconds{-10s}
+    }) {
+    test_relative<std::chrono::system_clock>(offset);
+    test_relative<std::chrono::system_clock>(offset - std::chrono::system_clock::now().time_since_epoch());
+    test_relative<std::chrono::steady_clock>(offset);
+    test_relative<std::chrono::steady_clock>(offset - std::chrono::steady_clock::now().time_since_epoch());
+  }
 }
index de0068d670ad85ec17ccca216ce9d0d0b1834cbe..ed6bd118fee44ad8f537166a65dbf1c2eb4cfae7 100644 (file)
@@ -24,6 +24,7 @@
 #include <chrono>
 #include <thread>
 #include <atomic>
+#include <initializer_list>
 #include <testsuite_hooks.h>
 
 void test01()
@@ -87,8 +88,31 @@ void test02()
   b.wait(1);
 }
 
+// Prove semaphore doesn't suffer from PR116586
+template <typename Clock>
+void
+test_absolute(std::chrono::nanoseconds offset)
+{
+  std::binary_semaphore sem(1);
+  std::chrono::time_point<Clock> tp(offset);
+  VERIFY(sem.try_acquire_until(tp));
+  VERIFY(!sem.try_acquire_until(tp));
+}
+
 int main()
 {
   test01();
   test02();
+  using namespace std::chrono;
+  for (const nanoseconds offset : {
+      // tv_sec == 0, tv_nsec == 0
+      nanoseconds{0},
+      // tv_sec == 0, tv_nsec < 0
+      nanoseconds{-10ms},
+      // tv_sec < 0
+      nanoseconds{-10s}
+    }) {
+    test_absolute<std::chrono::system_clock>(offset);
+    test_absolute<std::chrono::steady_clock>(offset);
+  }
 }