]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - libstdc++-v3/testsuite/30_threads/future/members/poll.cc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / 30_threads / future / members / poll.cc
index 54580579d3a1dc8f15703c61c5d651f44b087d03..4fa282bd87f764a48e205e0ec555751efc281d36 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2020 Free Software Foundation, Inc.
+// Copyright (C) 2020-2024 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
 
 // { dg-options "-O3" }
 // { dg-do run { target c++11 } }
+// { dg-additional-options "-pthread" { target pthread } }
+// { dg-require-gthreads "" }
 
 #include <future>
 #include <chrono>
 #include <iostream>
 #include <testsuite_hooks.h>
 
-const int iterations = 200;
+int iterations = 200;
 
 using namespace std;
 
@@ -43,39 +45,76 @@ int main()
   promise<int> p;
   future<int> f = p.get_future();
 
+ start_over:
   auto start = chrono::high_resolution_clock::now();
   for(int i = 0; i < iterations; i++)
     f.wait_for(chrono::seconds(0));
   auto stop = chrono::high_resolution_clock::now();
+
+  /* We've run too few iterations for the clock resolution.
+     Attempt to calibrate it.  */
+  if (start == stop)
+    {
+      /* After set_value, wait_for is faster, so use that for the
+        calibration to avoid zero at low clock resultions.  */
+      promise<int> pc;
+      future<int> fc = pc.get_future();
+      pc.set_value(1);
+
+      /* Loop until the clock advances, so that start is right after a
+        time increment.  */
+      do
+       start = chrono::high_resolution_clock::now();
+      while (start == stop);
+      int i = 0;
+      /* Now until the clock advances again, so that stop is right
+        after another time increment.  */
+      do
+       {
+         fc.wait_for(chrono::seconds(0));
+         stop = chrono::high_resolution_clock::now();
+         i++;
+       }
+      while (start == stop);
+      /* Go for some 10 cycles, but if we're already past that and
+        still get into the calibration loop, double the iteration
+        count and try again.  */
+      if (iterations < i * 10)
+       iterations = i * 10;
+      else
+       iterations *= 2;
+      goto start_over;
+    }
+
   double wait_for_0 = print("wait_for(0s)", stop - start);
 
   start = chrono::high_resolution_clock::now();
   for(int i = 0; i < iterations; i++)
-    f.wait_until(chrono::system_clock::time_point());
+    f.wait_until(chrono::system_clock::time_point::min());
   stop = chrono::high_resolution_clock::now();
-  double wait_until_sys_epoch __attribute__((unused))
-    = print("wait_until(system_clock epoch)", stop - start);
+  double wait_until_sys_min __attribute__((unused))
+    = print("wait_until(system_clock minimum)", stop - start);
 
   start = chrono::high_resolution_clock::now();
   for(int i = 0; i < iterations; i++)
-    f.wait_until(chrono::steady_clock::time_point());
+    f.wait_until(chrono::steady_clock::time_point::min());
   stop = chrono::high_resolution_clock::now();
-  double wait_until_steady_epoch __attribute__((unused))
-    = print("wait_until(steady_clock epoch", stop - start);
+  double wait_until_steady_min __attribute__((unused))
+    = print("wait_until(steady_clock minimum)", stop - start);
 
   start = chrono::high_resolution_clock::now();
   for(int i = 0; i < iterations; i++)
-    f.wait_until(chrono::system_clock::time_point::min());
+    f.wait_until(chrono::system_clock::time_point());
   stop = chrono::high_resolution_clock::now();
-  double wait_until_sys_min __attribute__((unused))
-    = print("wait_until(system_clock minimum)", stop - start);
+  double wait_until_sys_epoch __attribute__((unused))
+    = print("wait_until(system_clock epoch)", stop - start);
 
   start = chrono::high_resolution_clock::now();
   for(int i = 0; i < iterations; i++)
-    f.wait_until(chrono::steady_clock::time_point::min());
+    f.wait_until(chrono::steady_clock::time_point());
   stop = chrono::high_resolution_clock::now();
-  double wait_until_steady_min __attribute__((unused))
-    = print("wait_until(steady_clock minimum)", stop - start);
+  double wait_until_steady_epoch __attribute__((unused))
+    = print("wait_until(steady_clock epoch", stop - start);
 
   p.set_value(1);
 
@@ -85,19 +124,19 @@ int main()
   stop = chrono::high_resolution_clock::now();
   double ready = print("wait_for when ready", stop - start);
 
-  // polling before ready with wait_for(0s) should be almost as fast as
+  // Polling before ready with wait_for(0s) should be almost as fast as
   // after the result is ready.
-  VERIFY( wait_for_0 < (ready * 10) );
+  VERIFY( wait_for_0 < (ready * 30) );
+
+  // Polling before ready using wait_until(min) should not be terribly slow.
+  VERIFY( wait_until_sys_min < (ready * 100) );
+  VERIFY( wait_until_steady_min < (ready * 100) );
 
   // The following two tests fail with GCC 11, see
   // https://gcc.gnu.org/pipermail/libstdc++/2020-November/051422.html
 #if 0
-  // polling before ready using wait_until(epoch) should not be terribly slow.
+  // Polling before ready using wait_until(epoch) should not be terribly slow.
   VERIFY( wait_until_sys_epoch < (ready * 100) );
   VERIFY( wait_until_steady_epoch < (ready * 100) );
 #endif
-
-  // polling before ready using wait_until(min) should not be terribly slow.
-  VERIFY( wait_until_sys_min < (ready * 100) );
-  VERIFY( wait_until_steady_min < (ready * 100) );
 }