diff mbox series

[2/2] PR libstdc++/41861 Add full steady_clock support to condition_variable

Message ID 813a2918734ae172846d52f7d33f3dac34aabf9a.1563209229.git-series.mac@mcrowe.com
State New
Headers show
Series PR libstdc++/41861 Add full steady_clock support to condition_variable | expand

Commit Message

Mike Crowe July 15, 2019, 4:47 p.m. UTC
The pthread_cond_clockwait function was recently added[1] to glibc, and is
due to be released in glibc 2.30. If this function is available in the C
library it can be used it to fix
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=41861 by supporting
std::chrono::steady_clock properly with std::condition_variable.

This means that code using std::condition_variable::wait_for or
std::condition_variable::wait_until with std::chrono::steady_clock is no
longer subject to timing out early or potentially waiting for much longer
if the system clock is warped at an inopportune moment.

If pthread_cond_clockwait is available then std::chrono::steady_clock is
deemed to be the "best" clock available which means that it is used for the
relative wait_for calls and absolute wait_until calls using user-defined
clocks. Calls explicitly using std::chrono::system_clock continue to use
CLOCK_REALTIME via __gthread_cond_timedwait.

If pthread_cond_clockwait is not available then std::chrono::system_clock
is deemed to be the "best" clock available which means that the previous
suboptimal behaviour remains.

[1] https://sourceware.org/git/?p=glibc.git;a=commit;h=afe4de7d283ebd88157126c5494ce1796194c16e

libstdc++-v3/

	* include/std/condition_variable: Add include of <bits/c++config.h>
	to make _GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT available.
	(condition_variable): Split __clock_t into __system_clock_t, which
	is always system_clock and __best_clock_t, which is the clock that
	we wish to convert arbitrary other clocks to.  If we know that
	pthread_cond_clockwait is available then it is best to convert
	clocks to steady_clock, otherwise it's best to use
	system_clock. (wait_until): If pthread_cond_clockwait is available,
	provide a steady_clock overload.  Convert previous __clock_t
	overload to use __system_clock_t.  Convert generic overload to
	convert passed clock to __best_clock_t.  (wait_until_impl): Add
	steady_clock overload that calls pthread_cond_clockwait.  Convert
	previous __clock_t overload to use
	__system_clock_t. (condition_variable_any): Use steady_clock for
	__clock_t if pthread_cond_clockwait is available.

	* acinclude.m4:	Detect the availability of POSIX-proposed
	pthread_cond_clockwait function.
	* configure: Likewise.
	* configure.ac: Likewise.
	* config.h.in: Add _GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT define to
	indicate presence of pthread_cond_clockwait function.
---
 libstdc++-v3/ChangeLog                      | 25 +++++++-
 libstdc++-v3/acinclude.m4                   | 31 ++++++++-
 libstdc++-v3/config.h.in                    |  3 +-
 libstdc++-v3/configure                      | 83 ++++++++++++++++++++++-
 libstdc++-v3/configure.ac                   |  3 +-
 libstdc++-v3/include/std/condition_variable | 52 ++++++++++++--
 6 files changed, 191 insertions(+), 6 deletions(-)

Comments

Jonathan Wakely Sept. 4, 2019, 1:39 p.m. UTC | #1
On 15/07/19 17:47 +0100, Mike Crowe wrote:
>The pthread_cond_clockwait function was recently added[1] to glibc, and is
>due to be released in glibc 2.30. If this function is available in the C
>library it can be used it to fix
>https://gcc.gnu.org/bugzilla/show_bug.cgi?id=41861 by supporting
>std::chrono::steady_clock properly with std::condition_variable.
>
>This means that code using std::condition_variable::wait_for or
>std::condition_variable::wait_until with std::chrono::steady_clock is no
>longer subject to timing out early or potentially waiting for much longer
>if the system clock is warped at an inopportune moment.
>
>If pthread_cond_clockwait is available then std::chrono::steady_clock is
>deemed to be the "best" clock available which means that it is used for the
>relative wait_for calls and absolute wait_until calls using user-defined
>clocks. Calls explicitly using std::chrono::system_clock continue to use
>CLOCK_REALTIME via __gthread_cond_timedwait.
>
>If pthread_cond_clockwait is not available then std::chrono::system_clock
>is deemed to be the "best" clock available which means that the previous
>suboptimal behaviour remains.
>
>[1] https://sourceware.org/git/?p=glibc.git;a=commit;h=afe4de7d283ebd88157126c5494ce1796194c16e
>
>libstdc++-v3/
>
>	* include/std/condition_variable: Add include of <bits/c++config.h>
>	to make _GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT available.
>	(condition_variable): Split __clock_t into __system_clock_t, which
>	is always system_clock and __best_clock_t, which is the clock that
>	we wish to convert arbitrary other clocks to.  If we know that
>	pthread_cond_clockwait is available then it is best to convert
>	clocks to steady_clock, otherwise it's best to use
>	system_clock. (wait_until): If pthread_cond_clockwait is available,
>	provide a steady_clock overload.  Convert previous __clock_t
>	overload to use __system_clock_t.  Convert generic overload to
>	convert passed clock to __best_clock_t.  (wait_until_impl): Add
>	steady_clock overload that calls pthread_cond_clockwait.  Convert
>	previous __clock_t overload to use
>	__system_clock_t. (condition_variable_any): Use steady_clock for
>	__clock_t if pthread_cond_clockwait is available.
>
>	* acinclude.m4:	Detect the availability of POSIX-proposed
>	pthread_cond_clockwait function.
>	* configure: Likewise.
>	* configure.ac: Likewise.
>	* config.h.in: Add _GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT define to
>	indicate presence of pthread_cond_clockwait function.

Thanks, Mike!

This patch is much simpler than the previous versions. Thanks for
perservering with POSIX and glibc to get the necessary functionality
into libc.

I've attached a slightly-modified patch, which changes the names of
the clock typedefs in std::condition_variable. The names
"steady_clock" and "system_clock" are already reserved names, so we
can just use those (instead of the uglier __steady_clock_t forms). And
we can just keep the original __clock_t name to mean the best clock.
Does that look OK to you too?

I've confirmed that with glibc 2.30 the new function is detected, and
the testsuite passes. I'm running the tests with an older glibc as
well.

I noticed that the new tests you added in [PATCH 1/2] pass on current
trunk, even without [PATCH 2/2], is that expected?
Mike Crowe Sept. 4, 2019, 2:49 p.m. UTC | #2
On Wednesday 04 September 2019 at 14:39:35 +0100, Jonathan Wakely wrote:
> On 15/07/19 17:47 +0100, Mike Crowe wrote:
> > The pthread_cond_clockwait function was recently added[1] to glibc, and is
> > due to be released in glibc 2.30. If this function is available in the C
> > library it can be used it to fix
> > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=41861 by supporting
> > std::chrono::steady_clock properly with std::condition_variable.
> > 
> > This means that code using std::condition_variable::wait_for or
> > std::condition_variable::wait_until with std::chrono::steady_clock is no
> > longer subject to timing out early or potentially waiting for much longer
> > if the system clock is warped at an inopportune moment.
> > 
> > If pthread_cond_clockwait is available then std::chrono::steady_clock is
> > deemed to be the "best" clock available which means that it is used for the
> > relative wait_for calls and absolute wait_until calls using user-defined
> > clocks. Calls explicitly using std::chrono::system_clock continue to use
> > CLOCK_REALTIME via __gthread_cond_timedwait.
> > 
> > If pthread_cond_clockwait is not available then std::chrono::system_clock
> > is deemed to be the "best" clock available which means that the previous
> > suboptimal behaviour remains.
> > 
> > [1] https://sourceware.org/git/?p=glibc.git;a=commit;h=afe4de7d283ebd88157126c5494ce1796194c16e
> > 
> > libstdc++-v3/
> > 
> > 	* include/std/condition_variable: Add include of <bits/c++config.h>
> > 	to make _GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT available.
> > 	(condition_variable): Split __clock_t into __system_clock_t, which
> > 	is always system_clock and __best_clock_t, which is the clock that
> > 	we wish to convert arbitrary other clocks to.  If we know that
> > 	pthread_cond_clockwait is available then it is best to convert
> > 	clocks to steady_clock, otherwise it's best to use
> > 	system_clock. (wait_until): If pthread_cond_clockwait is available,
> > 	provide a steady_clock overload.  Convert previous __clock_t
> > 	overload to use __system_clock_t.  Convert generic overload to
> > 	convert passed clock to __best_clock_t.  (wait_until_impl): Add
> > 	steady_clock overload that calls pthread_cond_clockwait.  Convert
> > 	previous __clock_t overload to use
> > 	__system_clock_t. (condition_variable_any): Use steady_clock for
> > 	__clock_t if pthread_cond_clockwait is available.
> > 
> > 	* acinclude.m4:	Detect the availability of POSIX-proposed
> > 	pthread_cond_clockwait function.
> > 	* configure: Likewise.
> > 	* configure.ac: Likewise.
> > 	* config.h.in: Add _GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT define to
> > 	indicate presence of pthread_cond_clockwait function.
> 
> Thanks, Mike!
> 
> This patch is much simpler than the previous versions. Thanks for
> perservering with POSIX and glibc to get the necessary functionality
> into libc.
> 
> I've attached a slightly-modified patch, which changes the names of
> the clock typedefs in std::condition_variable. The names
> "steady_clock" and "system_clock" are already reserved names, so we
> can just use those (instead of the uglier __steady_clock_t forms). And
> we can just keep the original __clock_t name to mean the best clock.
> Does that look OK to you too?

You're far more expert on that stuff than I am, but it looks fine to me.

However, you've also removed the <bits/c++config.h> include. Was that
intentional?

> I've confirmed that with glibc 2.30 the new function is detected, and
> the testsuite passes. I'm running the tests with an older glibc as
> well.

I found that it was necessary to run the test under strace to prove that
the correct variant of futex is called too, because...

> 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.

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 ?

Thanks for looking at this.

Mike.
Jonathan Wakely Sept. 4, 2019, 4:14 p.m. UTC | #3
On 04/09/19 15:49 +0100, Mike Crowe wrote:
>On Wednesday 04 September 2019 at 14:39:35 +0100, Jonathan Wakely wrote:
>> On 15/07/19 17:47 +0100, Mike Crowe wrote:
>> > The pthread_cond_clockwait function was recently added[1] to glibc, and is
>> > due to be released in glibc 2.30. If this function is available in the C
>> > library it can be used it to fix
>> > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=41861 by supporting
>> > std::chrono::steady_clock properly with std::condition_variable.
>> >
>> > This means that code using std::condition_variable::wait_for or
>> > std::condition_variable::wait_until with std::chrono::steady_clock is no
>> > longer subject to timing out early or potentially waiting for much longer
>> > if the system clock is warped at an inopportune moment.
>> >
>> > If pthread_cond_clockwait is available then std::chrono::steady_clock is
>> > deemed to be the "best" clock available which means that it is used for the
>> > relative wait_for calls and absolute wait_until calls using user-defined
>> > clocks. Calls explicitly using std::chrono::system_clock continue to use
>> > CLOCK_REALTIME via __gthread_cond_timedwait.
>> >
>> > If pthread_cond_clockwait is not available then std::chrono::system_clock
>> > is deemed to be the "best" clock available which means that the previous
>> > suboptimal behaviour remains.
>> >
>> > [1] https://sourceware.org/git/?p=glibc.git;a=commit;h=afe4de7d283ebd88157126c5494ce1796194c16e
>> >
>> > libstdc++-v3/
>> >
>> > 	* include/std/condition_variable: Add include of <bits/c++config.h>
>> > 	to make _GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT available.
>> > 	(condition_variable): Split __clock_t into __system_clock_t, which
>> > 	is always system_clock and __best_clock_t, which is the clock that
>> > 	we wish to convert arbitrary other clocks to.  If we know that
>> > 	pthread_cond_clockwait is available then it is best to convert
>> > 	clocks to steady_clock, otherwise it's best to use
>> > 	system_clock. (wait_until): If pthread_cond_clockwait is available,
>> > 	provide a steady_clock overload.  Convert previous __clock_t
>> > 	overload to use __system_clock_t.  Convert generic overload to
>> > 	convert passed clock to __best_clock_t.  (wait_until_impl): Add
>> > 	steady_clock overload that calls pthread_cond_clockwait.  Convert
>> > 	previous __clock_t overload to use
>> > 	__system_clock_t. (condition_variable_any): Use steady_clock for
>> > 	__clock_t if pthread_cond_clockwait is available.
>> >
>> > 	* acinclude.m4:	Detect the availability of POSIX-proposed
>> > 	pthread_cond_clockwait function.
>> > 	* configure: Likewise.
>> > 	* configure.ac: Likewise.
>> > 	* config.h.in: Add _GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT define to
>> > 	indicate presence of pthread_cond_clockwait function.
>>
>> Thanks, Mike!
>>
>> This patch is much simpler than the previous versions. Thanks for
>> perservering with POSIX and glibc to get the necessary functionality
>> into libc.
>>
>> I've attached a slightly-modified patch, which changes the names of
>> the clock typedefs in std::condition_variable. The names
>> "steady_clock" and "system_clock" are already reserved names, so we
>> can just use those (instead of the uglier __steady_clock_t forms). And
>> we can just keep the original __clock_t name to mean the best clock.
>> Does that look OK to you too?
>
>You're far more expert on that stuff than I am, but it looks fine to me.
>
>However, you've also removed the <bits/c++config.h> include. Was that
>intentional?

Yes, it's already included via <type_traits> (and probably several
other routes). Every header should already be including that. If they
didn't, the macros like _GLIBCXX_HAS_GTHREADS, _GLIBCXX_VISIBILITY,
and _GLIBCXX_BEGIN_NAMESPACE_VERSION would produce errors.


>> I've confirmed that with glibc 2.30 the new function is detected, and
>> the testsuite passes. I'm running the tests with an older glibc as
>> well.
>
>I found that it was necessary to run the test under strace to prove that
>the correct variant of futex is called too, because...
>
>> 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 :-)

All my testing passed, so I'll get this committed today. Thanks again
for perservering to finally get this fixed!
Jonathan Wakely Sept. 4, 2019, 10:45 p.m. UTC | #4
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!
diff mbox series

Patch

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index a52a704..597000b 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,5 +1,30 @@ 
 2019-07-15  Mike Crowe  <mac@mcrowe.com>
 
+	* include/std/condition_variable: Add include of <bits/c++config.h>
+	to make _GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT available.
+	(condition_variable): Split __clock_t into __system_clock_t, which
+	is always system_clock and __best_clock_t, which is the clock that
+	we wish to convert arbitrary other clocks to.  If we know that
+	pthread_cond_clockwait is available then it is best to convert
+	clocks to steady_clock, otherwise it's best to use
+	system_clock. (wait_until): If pthread_cond_clockwait is available,
+	provide a steady_clock overload.  Convert previous __clock_t
+	overload to use __system_clock_t.  Convert generic overload to
+	convert passed clock to __best_clock_t.  (wait_until_impl): Add
+	steady_clock overload that calls pthread_cond_clockwait.  Convert
+	previous __clock_t overload to use
+	__system_clock_t. (condition_variable_any): Use steady_clock for
+	__clock_t if pthread_cond_clockwait is available.
+
+	* acinclude.m4:	Detect the availability of POSIX-proposed
+	pthread_cond_clockwait function.
+	* configure: Likewise.
+	* configure.ac: Likewise.
+	* config.h.in: Add _GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT define to
+	indicate presence of pthread_cond_clockwait function.
+
+2019-07-15  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
diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index 24145fd..35979e7 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -4194,6 +4194,37 @@  AC_DEFUN([GLIBCXX_CHECK_PTHREADS_NUM_PROCESSORS_NP], [
 ])
 
 dnl
+dnl Check whether pthread_cond_clockwait is available in <pthread.h> for std::condition_variable to use,
+dnl and define _GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT.
+dnl
+AC_DEFUN([GLIBCXX_CHECK_PTHREAD_COND_CLOCKWAIT], [
+
+  AC_LANG_SAVE
+  AC_LANG_CPLUSPLUS
+  ac_save_CXXFLAGS="$CXXFLAGS"
+  CXXFLAGS="$CXXFLAGS -fno-exceptions"
+  ac_save_LIBS="$LIBS"
+  LIBS="$LIBS -lpthread"
+
+  AC_MSG_CHECKING([for pthread_cond_clockwait])
+  AC_CACHE_VAL(glibcxx_cv_PTHREAD_COND_CLOCKWAIT, [
+    GCC_TRY_COMPILE_OR_LINK(
+      [#include <pthread.h>],
+      [pthread_mutex_t mutex; pthread_cond_t cond; struct timespec ts; int n = pthread_cond_clockwait(&cond, &mutex, 0, &ts);],
+      [glibcxx_cv_PTHREAD_COND_CLOCKWAIT=yes],
+      [glibcxx_cv_PTHREAD_COND_CLOCKWAIT=no])
+  ])
+  if test $glibcxx_cv_PTHREAD_COND_CLOCKWAIT = yes; then
+    AC_DEFINE(_GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT, 1, [Define if pthread_cond_clockwait is available in <pthread.h>.])
+  fi
+  AC_MSG_RESULT($glibcxx_cv_PTHREAD_COND_CLOCKWAIT)
+
+  CXXFLAGS="$ac_save_CXXFLAGS"
+  LIBS="$ac_save_LIBS"
+  AC_LANG_RESTORE
+])
+
+dnl
 dnl Check whether sysctl is available in <pthread.h>, and define _GLIBCXX_USE_SYSCTL_HW_NCPU.
 dnl
 AC_DEFUN([GLIBCXX_CHECK_SYSCTL_HW_NCPU], [
diff --git a/libstdc++-v3/config.h.in b/libstdc++-v3/config.h.in
index 99286e6..3d13402 100644
--- a/libstdc++-v3/config.h.in
+++ b/libstdc++-v3/config.h.in
@@ -991,6 +991,9 @@ 
 /* Define if pthreads_num_processors_np is available in <pthread.h>. */
 #undef _GLIBCXX_USE_PTHREADS_NUM_PROCESSORS_NP
 
+/* Define if pthread_cond_clockwait is available in <pthread.h>. */
+#undef _GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT
+
 /* Define if POSIX read/write locks are available in <gthr.h>. */
 #undef _GLIBCXX_USE_PTHREAD_RWLOCK_T
 
diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
index ab46399..c0b98d8 100755
--- a/libstdc++-v3/configure
+++ b/libstdc++-v3/configure
@@ -21581,6 +21581,89 @@  ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
 
+# For pthread_cond_clockwait
+
+
+
+  ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+  ac_save_CXXFLAGS="$CXXFLAGS"
+  CXXFLAGS="$CXXFLAGS -fno-exceptions"
+  ac_save_LIBS="$LIBS"
+  LIBS="$LIBS -lpthread"
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_cond_clockwait" >&5
+$as_echo_n "checking for pthread_cond_clockwait... " >&6; }
+  if test "${glibcxx_cv_PTHREAD_COND_CLOCKWAIT+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    if test x$gcc_no_link = xyes; then
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <pthread.h>
+int
+main ()
+{
+pthread_mutex_t mutex; pthread_cond_t cond; struct timespec ts; int n = pthread_cond_clockwait(&cond, &mutex, 0, &ts);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  glibcxx_cv_PTHREAD_COND_CLOCKWAIT=yes
+else
+  glibcxx_cv_PTHREAD_COND_CLOCKWAIT=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+  if test x$gcc_no_link = xyes; then
+  as_fn_error "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5
+fi
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <pthread.h>
+int
+main ()
+{
+pthread_mutex_t mutex; pthread_cond_t cond; struct timespec ts; int n = pthread_cond_clockwait(&cond, &mutex, 0, &ts);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  glibcxx_cv_PTHREAD_COND_CLOCKWAIT=yes
+else
+  glibcxx_cv_PTHREAD_COND_CLOCKWAIT=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+
+fi
+
+  if test $glibcxx_cv_PTHREAD_COND_CLOCKWAIT = yes; then
+
+$as_echo "#define _GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT 1" >>confdefs.h
+
+  fi
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_PTHREAD_COND_CLOCKWAIT" >&5
+$as_echo "$glibcxx_cv_PTHREAD_COND_CLOCKWAIT" >&6; }
+
+  CXXFLAGS="$ac_save_CXXFLAGS"
+  LIBS="$ac_save_LIBS"
+  ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
 
   ac_fn_c_check_header_mongrel "$LINENO" "locale.h" "ac_cv_header_locale_h" "$ac_includes_default"
 if test "x$ac_cv_header_locale_h" = xyes; then :
diff --git a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac
index 80d8202..ad4ae0c 100644
--- a/libstdc++-v3/configure.ac
+++ b/libstdc++-v3/configure.ac
@@ -220,6 +220,9 @@  GLIBCXX_ENABLE_LIBSTDCXX_TIME
 # Check for tmpnam which is obsolescent in POSIX.1-2008
 GLIBCXX_CHECK_TMPNAM
 
+# For pthread_cond_clockwait
+GLIBCXX_CHECK_PTHREAD_COND_CLOCKWAIT
+
 AC_LC_MESSAGES
 
 # For hardware_concurrency
diff --git a/libstdc++-v3/include/std/condition_variable b/libstdc++-v3/include/std/condition_variable
index a83996a..0e1bdf7 100644
--- a/libstdc++-v3/include/std/condition_variable
+++ b/libstdc++-v3/include/std/condition_variable
@@ -35,6 +35,7 @@ 
 # include <bits/c++0x_warning.h>
 #else
 
+#include <bits/c++config.h>
 #include <chrono>
 #include <bits/std_mutex.h>
 #include <bits/unique_lock.h>
@@ -65,8 +66,13 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
   /// condition_variable
   class condition_variable
   {
-    typedef chrono::system_clock	__clock_t;
     typedef chrono::steady_clock	__steady_clock_t;
+#if defined(_GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT)
+    typedef chrono::steady_clock	__best_clock_t;
+#else
+    typedef chrono::system_clock	__best_clock_t;
+#endif
+    typedef chrono::system_clock	__system_clock_t;
     typedef __gthread_cond_t		__native_type;
 
 #ifdef __GTHREAD_COND_INIT
@@ -101,10 +107,18 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	  wait(__lock);
       }
 
+#if defined(_GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT)
+    template<typename _Duration>
+      cv_status
+      wait_until(unique_lock<mutex>& __lock,
+		 const chrono::time_point<__steady_clock_t, _Duration>& __atime)
+      { return __wait_until_impl(__lock, __atime); }
+#endif
+
     template<typename _Duration>
       cv_status
       wait_until(unique_lock<mutex>& __lock,
-		 const chrono::time_point<__clock_t, _Duration>& __atime)
+		 const chrono::time_point<__system_clock_t, _Duration>& __atime)
       { return __wait_until_impl(__lock, __atime); }
 
     template<typename _Clock, typename _Duration>
@@ -112,9 +126,8 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       wait_until(unique_lock<mutex>& __lock,
 		 const chrono::time_point<_Clock, _Duration>& __atime)
       {
-	// DR 887 - Sync unknown clock to known clock.
 	const typename _Clock::time_point __c_entry = _Clock::now();
-	const __clock_t::time_point __s_entry = __clock_t::now();
+	const __best_clock_t::time_point __s_entry = __best_clock_t::now();
 	const auto __delta = __atime - __c_entry;
 	const auto __s_atime = __s_entry + __delta;
 
@@ -171,10 +184,33 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
     { return &_M_cond; }
 
   private:
+#if defined(_GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT)
+    template<typename _Dur>
+      cv_status
+      __wait_until_impl(unique_lock<mutex>& __lock,
+			const chrono::time_point<__steady_clock_t, _Dur>& __atime)
+      {
+	auto __s = chrono::time_point_cast<chrono::seconds>(__atime);
+	auto __ns = chrono::duration_cast<chrono::nanoseconds>(__atime - __s);
+
+	__gthread_time_t __ts =
+	  {
+	    static_cast<std::time_t>(__s.time_since_epoch().count()),
+	    static_cast<long>(__ns.count())
+	  };
+
+	pthread_cond_clockwait(&_M_cond, __lock.mutex()->native_handle(),
+					 CLOCK_MONOTONIC,
+					 &__ts);
+
+	return (__steady_clock_t::now() < __atime
+		? cv_status::no_timeout : cv_status::timeout);
+      }
+#endif
     template<typename _Dur>
       cv_status
       __wait_until_impl(unique_lock<mutex>& __lock,
-			const chrono::time_point<__clock_t, _Dur>& __atime)
+			const chrono::time_point<__system_clock_t, _Dur>& __atime)
       {
 	auto __s = chrono::time_point_cast<chrono::seconds>(__atime);
 	auto __ns = chrono::duration_cast<chrono::nanoseconds>(__atime - __s);
@@ -188,7 +224,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	__gthread_cond_timedwait(&_M_cond, __lock.mutex()->native_handle(),
 				 &__ts);
 
-	return (__clock_t::now() < __atime
+	return (__system_clock_t::now() < __atime
 		? cv_status::no_timeout : cv_status::timeout);
       }
   };
@@ -208,7 +244,11 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // Like above, but mutex is not required to have try_lock.
   class condition_variable_any
   {
+#if defined(_GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT)
+    typedef chrono::steady_clock	__clock_t;
+#else
     typedef chrono::system_clock	__clock_t;
+#endif
     condition_variable			_M_cond;
     shared_ptr<mutex>			_M_mutex;