[2/2] condition_variable: Use steady_clock to implement wait_for

Message ID e9f2b02b0926e473511b0fe941c260fbead4c81c.1532105301.git-series.mac@mcrowe.com
State New
Headers show
Series
  • [1/2] condition_variable: Report early wakeup of wait_until as no_timeout
Related show

Commit Message

Mike Crowe July 20, 2018, 4:49 p.m.
I believe[1][2] that the C++ standard says that
std::condition_variable::wait_for should be implemented to be equivalent
to:

 return wait_until(lock, chrono::steady_clock::now() + rel_time);

But the existing implementation uses chrono::system_clock. Now that
wait_until has potentially-different behaviour for chrono::steady_clock,
let's at least try to wait using the correct clock.

[1] https://en.cppreference.com/w/cpp/thread/condition_variable/wait_for
[2] https://github.com/cplusplus/draft/blob/master/source/threads.tex
---
 libstdc++-v3/ChangeLog                      | 3 +++
 libstdc++-v3/include/std/condition_variable | 5 +++--
 2 files changed, 6 insertions(+), 2 deletions(-)

--
git-series 0.9.1
BrightSign considers your privacy to be very important. The emails you send to us will be protected and secured. Furthermore, we will only use your email and contact information for the reasons you sent them to us and for tracking how effectively we respond to your requests.

Comments

Jonathan Wakely Aug. 1, 2018, 3:41 p.m. | #1
On 20/07/18 17:49 +0100, Mike Crowe wrote:
>I believe[1][2] that the C++ standard says that

>std::condition_variable::wait_for should be implemented to be equivalent

>to:

>

> return wait_until(lock, chrono::steady_clock::now() + rel_time);

>

>But the existing implementation uses chrono::system_clock. Now that

>wait_until has potentially-different behaviour for chrono::steady_clock,

>let's at least try to wait using the correct clock.

>

>[1] https://en.cppreference.com/w/cpp/thread/condition_variable/wait_for

>[2] https://github.com/cplusplus/draft/blob/master/source/threads.tex


Also committed to trunk. Thanks again.

>---

> libstdc++-v3/ChangeLog                      | 3 +++

> libstdc++-v3/include/std/condition_variable | 5 +++--

> 2 files changed, 6 insertions(+), 2 deletions(-)

>

>diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog

>index 4657af7..432cb84 100644

>--- a/libstdc++-v3/ChangeLog

>+++ b/libstdc++-v3/ChangeLog

>@@ -1,4 +1,7 @@

> 2018-07-20  Mike Crowe <mac@mcrowe.com>

>+       * include/std/condition_variable (wait_for): Use steady_clock.

>+

>+2018-07-20  Mike Crowe <mac@mcrowe.com>

>        * include/std/condition_variable (wait_until): Only report timeout

>        if we really have timed out when measured against the

>        caller-supplied clock.

>diff --git a/libstdc++-v3/include/std/condition_variable b/libstdc++-v3/include/std/condition_variable

>index a2d146a..ce58399 100644

>--- a/libstdc++-v3/include/std/condition_variable

>+++ b/libstdc++-v3/include/std/condition_variable

>@@ -65,6 +65,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION

>   class condition_variable

>   {

>     typedef chrono::system_clock       __clock_t;

>+    typedef chrono::steady_clock       __steady_clock_t;

>     typedef __gthread_cond_t           __native_type;

>

> #ifdef __GTHREAD_COND_INIT

>@@ -142,11 +143,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION

>       wait_for(unique_lock<mutex>& __lock,

>               const chrono::duration<_Rep, _Period>& __rtime)

>       {

>-       using __dur = typename __clock_t::duration;

>+       using __dur = typename __steady_clock_t::duration;

>        auto __reltime = chrono::duration_cast<__dur>(__rtime);

>        if (__reltime < __rtime)

>          ++__reltime;

>-       return wait_until(__lock, __clock_t::now() + __reltime);

>+       return wait_until(__lock, __steady_clock_t::now() + __reltime);

>       }

>

>     template<typename _Rep, typename _Period, typename _Predicate>

>--

>git-series 0.9.1

>BrightSign considers your privacy to be very important. The emails you send to us will be protected and secured. Furthermore, we will only use your email and contact information for the reasons you sent them to us and for tracking how effectively we respond to your requests.

Patch

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 4657af7..432cb84 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,4 +1,7 @@ 
 2018-07-20  Mike Crowe <mac@mcrowe.com>
+       * include/std/condition_variable (wait_for): Use steady_clock.
+
+2018-07-20  Mike Crowe <mac@mcrowe.com>
        * include/std/condition_variable (wait_until): Only report timeout
        if we really have timed out when measured against the
        caller-supplied clock.
diff --git a/libstdc++-v3/include/std/condition_variable b/libstdc++-v3/include/std/condition_variable
index a2d146a..ce58399 100644
--- a/libstdc++-v3/include/std/condition_variable
+++ b/libstdc++-v3/include/std/condition_variable
@@ -65,6 +65,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
   class condition_variable
   {
     typedef chrono::system_clock       __clock_t;
+    typedef chrono::steady_clock       __steady_clock_t;
     typedef __gthread_cond_t           __native_type;

 #ifdef __GTHREAD_COND_INIT
@@ -142,11 +143,11 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       wait_for(unique_lock<mutex>& __lock,
               const chrono::duration<_Rep, _Period>& __rtime)
       {
-       using __dur = typename __clock_t::duration;
+       using __dur = typename __steady_clock_t::duration;
        auto __reltime = chrono::duration_cast<__dur>(__rtime);
        if (__reltime < __rtime)
          ++__reltime;
-       return wait_until(__lock, __clock_t::now() + __reltime);
+       return wait_until(__lock, __steady_clock_t::now() + __reltime);
       }

     template<typename _Rep, typename _Period, typename _Predicate>