Add user-defined clock to libstdc++ condition_variable tests
authorMike Crowe <mac@mcrowe.com>
Wed, 4 Sep 2019 22:43:20 +0000 (22:43 +0000)
committerJonathan Wakely <redi@gcc.gnu.org>
Wed, 4 Sep 2019 22:43:20 +0000 (23:43 +0100)
2019-09-04  Mike Crowe  <mac@mcrowe.com>

* testsuite/30_threads/condition_variable/members/2.cc (test01):
Parameterise so that test can be run against an arbitrary clock.
(main): Test using std::chrono::steady_clock and a user-defined
clock in addition to the previous std::chrono::system_clock.
* testsuite/30_threads/condition_variable_any/members/2.cc: Likewise.

From-SVN: r275389

libstdc++-v3/ChangeLog
libstdc++-v3/testsuite/30_threads/condition_variable/members/2.cc
libstdc++-v3/testsuite/30_threads/condition_variable_any/members/2.cc

index b130f0f55225a20de8159e68447858942b78348d..678706dc94f3d143548d3a5ddbde4e79bd543b5e 100644 (file)
@@ -1,3 +1,11 @@
+2019-09-04  Mike Crowe  <mac@mcrowe.com>
+
+       * testsuite/30_threads/condition_variable/members/2.cc (test01):
+       Parameterise so that test can be run against an arbitrary clock.
+       (main): Test using std::chrono::steady_clock and a user-defined
+       clock in addition to the previous std::chrono::system_clock.
+       * testsuite/30_threads/condition_variable_any/members/2.cc: Likewise.
+
 2019-09-03  Ulrich Weigand  <uweigand@de.ibm.com>
 
        * crossconfig.m4: Remove references to spu.
index 0ecb09d80ed1b7c05b38dc30c84012ea0151fd69..cbac3fa1932e4530d5d1443773ded89d0806b46c 100644 (file)
@@ -26,6 +26,7 @@
 #include <system_error>
 #include <testsuite_hooks.h>
 
+template <typename ClockType>
 void test01()
 {
   try 
@@ -35,10 +36,10 @@ void test01()
       std::mutex m;
       std::unique_lock<std::mutex> l(m);
 
-      auto then = std::chrono::steady_clock::now();
+      auto then = ClockType::now();
       std::cv_status result = c1.wait_until(l, then + ms);
       VERIFY( result == std::cv_status::timeout );
-      VERIFY( (std::chrono::steady_clock::now() - then) >= ms );
+      VERIFY( (ClockType::now() - then) >= ms );
       VERIFY( l.owns_lock() );
     }
   catch (const std::system_error& e)
@@ -102,9 +103,39 @@ void test01_alternate_clock()
     }
 }
 
+/* User defined clock that ticks in two-thousandths of a second
+   forty-two minutes ahead of steady_clock. */
+struct user_defined_clock
+{
+  typedef std::chrono::steady_clock::rep rep;
+  typedef std::ratio<1, 2000> period;
+  typedef std::chrono::duration<rep, period> duration;
+  typedef std::chrono::time_point<user_defined_clock> time_point;
+
+  static constexpr bool is_steady = true;
+
+  static time_point now() noexcept
+  {
+    using namespace std::chrono;
+    const auto steady_since_epoch = steady_clock::now().time_since_epoch();
+    const auto user_since_epoch = duration_cast<duration>(steady_since_epoch);
+    return time_point(user_since_epoch + minutes(42));
+  }
+};
+
+/*
+It's not possible for this test to automatically ensure that the
+system_clock test cases result in a wait on CLOCK_REALTIME and steady_clock
+test cases result in a wait on CLOCK_MONOTONIC. It's recommended to run the
+test under strace(1) and check whether the expected futex calls are made by
+glibc. See https://gcc.gnu.org/ml/libstdc++/2019-09/msg00022.html for
+instructions.
+*/
+
 int main()
 {
-  test01();
+  test01<std::chrono::steady_clock>();
+  test01<std::chrono::system_clock>();
+  test01<user_defined_clock>();
   test01_alternate_clock();
-  return 0;
 }
index e6fbc44f6f95e4c03fdfe8a78e9d259d1a7e0006..897fa86f51492e33bffdc4a3974a69cb956247f5 100644 (file)
@@ -51,6 +51,7 @@ struct Mutex
 };
 
 
+template <typename ClockType>
 void test01()
 {
   try 
@@ -60,10 +61,10 @@ void test01()
       Mutex m;
       m.lock();
 
-      auto then = std::chrono::steady_clock::now();
+      auto then = ClockType::now();
       std::cv_status result = c1.wait_until(m, then + ms);
       VERIFY( result == std::cv_status::timeout );
-      VERIFY( (std::chrono::steady_clock::now() - then) >= ms );
+      VERIFY( (ClockType::now() - then) >= ms );
       VERIFY( m.locked );
     }
   catch (const std::system_error& e)
@@ -76,8 +77,29 @@ void test01()
     }
 }
 
+/* User defined clock that ticks in two-thousandths of a second
+   forty-two minutes ahead of steady_clock. */
+struct user_defined_clock
+{
+  typedef std::chrono::steady_clock::rep rep;
+  typedef std::ratio<1, 2000> period;
+  typedef std::chrono::duration<rep, period> duration;
+  typedef std::chrono::time_point<user_defined_clock> time_point;
+
+  static constexpr bool is_steady = true;
+
+  static time_point now() noexcept
+  {
+    using namespace std::chrono;
+    const auto steady_since_epoch = steady_clock::now().time_since_epoch();
+    const auto user_since_epoch = duration_cast<duration>(steady_since_epoch);
+    return time_point(user_since_epoch + minutes(42));
+  }
+};
+
 int main()
 {
-  test01();
-  return 0;
+  test01<std::chrono::steady_clock>();
+  test01<std::chrono::system_clock>();
+  test01<user_defined_clock>();
 }