public inbox for libstdc++@gcc.gnu.org
 help / color / mirror / Atom feed
From: Jonathan Wakely <jwakely@redhat.com>
To: Mike Crowe <mac@mcrowe.com>
Cc: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org
Subject: Re: [PATCH 2/2] PR libstdc++/41861 Add full steady_clock support to condition_variable
Date: Wed, 04 Sep 2019 22:46:00 -0000	[thread overview]
Message-ID: <20190904224546.GK9487@redhat.com> (raw)
In-Reply-To: <20190904172145.GA11970@mcrowe.com>

[-- Attachment #1: Type: text/plain, Size: 3053 bytes --]

On 04/09/19 18:21 +0100, Mike Crowe wrote:
>On Wednesday 04 September 2019 at 17:57:45 +0100, Mike Crowe wrote:
>> On Wednesday 04 September 2019 at 17:14:30 +0100, Jonathan Wakely wrote:
>> > On 04/09/19 15:49 +0100, Mike Crowe wrote:
>> > > On Wednesday 04 September 2019 at 14:39:35 +0100, Jonathan Wakely wrote:
>> > > > I noticed that the new tests you added in [PATCH 1/2] pass on current
>> > > > trunk, even without [PATCH 2/2], is that expected?
>> > >
>> > > Unfortunately, yes. CLOCK_MONOTONIC and CLOCK_REALTIME will tick at the
>> > > same rate, so unless someone warps CLOCK_REALTIME during the test we can't
>> > > tell the difference between the old implementation of translating
>> > > steady_clock to system_clock and the new implementation that uses
>> > > steady_clock directly. :( I added the tests in the hope of finding other
>> > > mistakes in the new implementation rather than to reproduce the original
>> > > problem.
>> >
>> > OK, that was what I figured was the case. Thanks for confirming.
>> >
>> > > Maybe I should add comments to the test to make that clear along the lines
>> > > of those found in testsuite/27_io/objects/char/3_xin.cc ?
>> >
>> > More comments are usually useful, otherwise I'll just ask the same
>> > question again and again :-)
>>
>> How about something like:
>>
>> --8<--
>> 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.
>> -->8--
>>
>> Unfortunately I'm unable to determine how I actually managed to run the
>> test under strace. Perhaps I just compiled a similar test myself rather
>> than using dejagnu. :(
>
>Ah, I did it. Here's a new comment:
>
>--8<--
>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. The easiest way to do this is to copy and paste the line used to
>build the test from the output of:
>
> make -j8 check-target-libstdc++-v3 RUNTESTFLAGS="conformance.exp=30_threads/condition_variable/members/* -v -v"
>
>to compile the test with only the tests for one clock enabled and then run it as:
>
> strace ./2.exe
>
>You should see calls to:
>
> futex(..., FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME, ...)
>
>with large values of tv_sec when using system_clock and calls to:
>
> futex(..., FUTEX_WAIT_BITSET_PRIVATE, ...)
>
>with values of tv_sec based on the system uptime when using steady_clock.
>-->8--

Great. I've committed the patch I sent earlier (with the renamed
typedefs) and the attached one for the tests (using an abridged form
of the comment above, linking to the copy of your mail in the list
archives for the full instructions).

Thanks!


[-- Attachment #2: patch.txt --]
[-- Type: text/x-patch, Size: 4733 bytes --]

commit 8f84bffbd3c4173d684fc825f0847d857a71f54b
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Sep 4 12:41:34 2019 +0100

    Add user-defined clock to libstdc++ condition_variable tests
    
    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.

diff --git a/libstdc++-v3/testsuite/30_threads/condition_variable/members/2.cc b/libstdc++-v3/testsuite/30_threads/condition_variable/members/2.cc
index 0ecb09d80ed..cbac3fa1932 100644
--- a/libstdc++-v3/testsuite/30_threads/condition_variable/members/2.cc
+++ b/libstdc++-v3/testsuite/30_threads/condition_variable/members/2.cc
@@ -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;
 }
diff --git a/libstdc++-v3/testsuite/30_threads/condition_variable_any/members/2.cc b/libstdc++-v3/testsuite/30_threads/condition_variable_any/members/2.cc
index e6fbc44f6f9..897fa86f514 100644
--- a/libstdc++-v3/testsuite/30_threads/condition_variable_any/members/2.cc
+++ b/libstdc++-v3/testsuite/30_threads/condition_variable_any/members/2.cc
@@ -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>();
 }

  reply	other threads:[~2019-09-04 22:46 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-07-15 16:48 [PATCH 0/2] " Mike Crowe
2019-07-15 16:48 ` [PATCH 2/2] " Mike Crowe
2019-09-04 13:39   ` Jonathan Wakely
2019-09-04 14:49     ` Mike Crowe
2019-09-04 16:14       ` Jonathan Wakely
2019-09-04 16:57         ` Mike Crowe
2019-09-04 17:21           ` Mike Crowe
2019-09-04 22:46             ` Jonathan Wakely [this message]
2019-07-15 16:51 ` [PATCH 1/2] Add user-defined clock to libstdc++ condition_variable tests Mike Crowe
2019-08-19 16:27 ` [PATCH 0/2] PR libstdc++/41861 Add full steady_clock support to condition_variable Mike Crowe

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190904224546.GK9487@redhat.com \
    --to=jwakely@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=libstdc++@gcc.gnu.org \
    --cc=mac@mcrowe.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).