diff mbox

fix libstdc++/54562

Message ID CAH6eHdSDdbsYWKWn3Rr6WP30dSzwOsD8ske9kZDhXCc=0B+p1Q@mail.gmail.com
State New
Headers show

Commit Message

Jonathan Wakely Nov. 11, 2013, 1:33 p.m. UTC
This ensures that the standard timed mutexes use steady_clock for
relative timeouts and the same clock as pthread_mutex_timedlock for
absolute timeouts.

I'm not adding a new test as the only ones I could come up with
involve waiting for longer than is suitable in a testcase, and don't
reliably fail on all systems anyway.

        PR libstdc++/54562
        * include/std/mutex (__timed_mutex_impl::__clock_t): Use
        high_resolution_clock for absolute timeouts, because
        pthread_mutex_timedlock uses CLOCK_REALTIME not CLOCK_MONOTONIC.
        (__timed_mutex_impl::_M_try_lock_for): Use steady_clock for relative
        timeouts as per [thread.req.timing].
        (__timed_mutex_impl::_M_try_lock_until<Clock,Duration>): Convert to
        __clock_t time point instead of using _M_try_lock_for.

Tested x86_64-linux, committed to trunk.  I would like to commit this
to the 4.8 branch too, but I'm undecided whether it's suitable.
commit 1f2401b0338fefaaa521ebf202e563a6c673b47e
Author: Jonathan Wakely <jwakely.gcc@gmail.com>
Date:   Mon Nov 11 12:40:01 2013 +0000

    	PR libstdc++/54562
    	* include/std/mutex (__timed_mutex_impl::__clock_t): Use
    	high_resolution_clock for absolute timeouts, because
    	pthread_mutex_timedlock uses CLOCK_REALTIME not CLOCK_MONOTONIC.
    	(__timed_mutex_impl::_M_try_lock_for): Use steady_clock for relative
    	timeouts as per [thread.req.timing].
    	(__timed_mutex_impl::_M_try_lock_until<Clock,Duration>): Convert to
    	__clock_t time point instead of using _M_try_lock_for.
diff mbox

Patch

diff --git a/libstdc++-v3/include/std/mutex b/libstdc++-v3/include/std/mutex
index 40b2e31..da2ca0c 100644
--- a/libstdc++-v3/include/std/mutex
+++ b/libstdc++-v3/include/std/mutex
@@ -203,21 +203,17 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
     class __timed_mutex_impl
     {
     protected:
-#ifdef _GLIBCXX_USE_CLOCK_MONOTONIC
-      typedef chrono::steady_clock 	  	__clock_t;
-#else
       typedef chrono::high_resolution_clock 	__clock_t;
-#endif
 
       template<typename _Rep, typename _Period>
 	bool
 	_M_try_lock_for(const chrono::duration<_Rep, _Period>& __rtime)
 	{
-	  auto __rt = chrono::duration_cast<__clock_t::duration>(__rtime);
-	  if (ratio_greater<__clock_t::period, _Period>())
+	  using chrono::steady_clock;
+	  auto __rt = chrono::duration_cast<steady_clock::duration>(__rtime);
+	  if (ratio_greater<steady_clock::period, _Period>())
 	    ++__rt;
-
-	  return _M_try_lock_until(__clock_t::now() + __rt);
+	  return _M_try_lock_until(steady_clock::now() + __rt);
 	}
 
       template<typename _Duration>
@@ -225,11 +221,8 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	_M_try_lock_until(const chrono::time_point<__clock_t,
 						   _Duration>& __atime)
 	{
-	  chrono::time_point<__clock_t, chrono::seconds> __s =
-	    chrono::time_point_cast<chrono::seconds>(__atime);
-
-	  chrono::nanoseconds __ns =
-	    chrono::duration_cast<chrono::nanoseconds>(__atime - __s);
+	  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()),
@@ -243,7 +236,10 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       template<typename _Clock, typename _Duration>
 	bool
 	_M_try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime)
-	{ return _M_try_lock_for(__atime - _Clock::now()); }
+	{
+	  auto __rtime = __atime - _Clock::now();
+	  return _M_try_lock_until(__clock_t::now() + __rtime);
+	}
     };
 
   /// timed_mutex