This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] libstdc++/65704 portable timed_mutex and recursive_timed_mutex


This provides alternative implementations of std::timed_mutex and
std::recursive_timed_mutex for targets that don't support the
_POSIX_TIMEOUTS option (darwin and maybe HPUX).

The new versions need to use std::condition_variable, which depends on
std::mutex, so I have moved std::mutex, std::lock_guard, and
std::unique_lock into a new header, <bits/mutex.h> so that <mutex> can
do:

 #include <bits/mutex.h>
 #if ! _GTHREAD_USE_MUTEX_TIMEDLOCK
 # include <condition_variable>
 # include <thread>
 #endif
 ...
 #if _GTHREAD_USE_MUTEX_TIMEDLOCK
 // existing implementations using pthread_mutex_t
 #else
 // new implementations using std::condition_variable
 #endif

The new smaller <bits/mutex.h> header has the advantage that other
libstdc++ headers which only need std::mutex and the scoped locks can
include <bits/mutex.h>. We should only include <mutex> when we need
timed or recursive mutexes, or std::call_once.

Tested powerpc64le-linux as normal, and again with #undef
_GTHREAD_USE_MUTEX_TIMEDLOCK to test the new code.

commit 03a2d83efd54483a1b19d3fa499757fbd40cf8ef
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Fri Sep 4 10:39:42 2015 +0100

    Add portable timed_mutex and recursive_timed_mutex.
    
    	PR libstdc++/65704
    	* include/Makefile.am: Add <bits/mutex.h>.
    	* include/Makefile.in: Regenerate.
    	* include/bits/mutex.h (__mutex_base, mutex, lock_guard, unique_lock):
    	New file containing types moved from <mutex>.
    	* include/std/condition_variable: Include <bits/mutex.h> instead of
    	<mutex>.
    	* include/std/mutex (__mutex_base, mutex, lock_guard, unique_lock):
    	Move to <bits/mutex.h>.
    	*  testsuite/30_threads/recursive_timed_mutex/cons/1.cc: Remove
    	dg-require-gthreads-timed.
    	*  testsuite/30_threads/recursive_timed_mutex/cons/assign_neg.cc:
    	Likewise.
    	*  testsuite/30_threads/recursive_timed_mutex/cons/copy_neg.cc:
    	Likewise.
    	*  testsuite/30_threads/recursive_timed_mutex/dest/
    	destructor_locked.cc: Likewise.
    	*  testsuite/30_threads/recursive_timed_mutex/lock/1.cc: Likewise.
    	*  testsuite/30_threads/recursive_timed_mutex/lock/2.cc: Likewise.
    	*  testsuite/30_threads/recursive_timed_mutex/try_lock/1.cc: Likewise.
    	*  testsuite/30_threads/recursive_timed_mutex/try_lock/2.cc: Likewise.
    	*  testsuite/30_threads/recursive_timed_mutex/try_lock_for/1.cc:
    	Likewise.
    	*  testsuite/30_threads/recursive_timed_mutex/try_lock_for/2.cc:
    	Likewise.
    	*  testsuite/30_threads/recursive_timed_mutex/try_lock_for/3.cc:
    	Likewise.
    	*  testsuite/30_threads/recursive_timed_mutex/try_lock_until/1.cc:
    	Likewise.
    	*  testsuite/30_threads/recursive_timed_mutex/try_lock_until/2.cc:
    	Likewise.
    	*  testsuite/30_threads/recursive_timed_mutex/unlock/1.cc: Likewise.
    	*  testsuite/30_threads/timed_mutex/cons/1.cc: Likewise.
    	*  testsuite/30_threads/timed_mutex/cons/assign_neg.cc: Likewise.
    	*  testsuite/30_threads/timed_mutex/cons/copy_neg.cc: Likewise.
    	*  testsuite/30_threads/timed_mutex/dest/destructor_locked.cc:
    	Likewise.
    	*  testsuite/30_threads/timed_mutex/lock/1.cc: Likewise.
    	*  testsuite/30_threads/timed_mutex/requirements/standard_layout.cc:
    	Likewise.
    	*  testsuite/30_threads/timed_mutex/try_lock/1.cc: Likewise.
    	*  testsuite/30_threads/timed_mutex/try_lock/2.cc: Likewise.
    	*  testsuite/30_threads/timed_mutex/try_lock_for/1.cc: Likewise.
    	*  testsuite/30_threads/timed_mutex/try_lock_for/2.cc: Likewise.
    	*  testsuite/30_threads/timed_mutex/try_lock_for/3.cc: Likewise.
    	*  testsuite/30_threads/timed_mutex/try_lock_until/1.cc: Likewise.
    	*  testsuite/30_threads/timed_mutex/try_lock_until/2.cc: Likewise.
    	*  testsuite/30_threads/timed_mutex/try_lock_until/57641.cc: Likewise.
    	*  testsuite/30_threads/timed_mutex/unlock/1.cc: Likewise.
    	*  testsuite/30_threads/unique_lock/cons/5.cc: Likewise.
    	*  testsuite/30_threads/unique_lock/cons/6.cc: Likewise.
    	*  testsuite/30_threads/unique_lock/locking/3.cc: Likewise.
    	*  testsuite/30_threads/unique_lock/locking/4.cc: Likewise.

diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index 41fc4af..3edb914 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -122,6 +122,7 @@ bits_headers = \
 	${bits_srcdir}/mask_array.h \
 	${bits_srcdir}/memoryfwd.h \
 	${bits_srcdir}/move.h \
+	${bits_srcdir}/mutex.h \
 	${bits_srcdir}/ostream.tcc \
 	${bits_srcdir}/ostream_insert.h \
 	${bits_srcdir}/parse_numbers.h \
diff --git a/libstdc++-v3/include/bits/mutex.h b/libstdc++-v3/include/bits/mutex.h
new file mode 100644
index 0000000..43f5b0b
--- /dev/null
+++ b/libstdc++-v3/include/bits/mutex.h
@@ -0,0 +1,360 @@
+// std::mutex implementation -*- C++ -*-
+
+// Copyright (C) 2003-2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file bits/mutex.h
+ *  This is an internal header file, included by other library headers.
+ *  Do not attempt to use it directly. @headername{mutex}
+ */
+
+#ifndef _GLIBCXX_MUTEX_H
+#define _GLIBCXX_MUTEX_H 1
+
+#pragma GCC system_header
+
+#if __cplusplus < 201103L
+# include <bits/c++0x_warning.h>
+#else
+
+#include <system_error>
+#include <bits/functexcept.h>
+#include <bits/gthr.h>
+#include <bits/move.h> // for std::swap
+
+#ifdef _GLIBCXX_USE_C99_STDINT_TR1
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  /**
+   * @defgroup mutexes Mutexes
+   * @ingroup concurrency
+   *
+   * Classes for mutex support.
+   * @{
+   */
+
+#ifdef _GLIBCXX_HAS_GTHREADS
+  // Common base class for std::mutex and std::timed_mutex
+  class __mutex_base
+  {
+  protected:
+    typedef __gthread_mutex_t			__native_type;
+
+#ifdef __GTHREAD_MUTEX_INIT
+    __native_type  _M_mutex = __GTHREAD_MUTEX_INIT;
+
+    constexpr __mutex_base() noexcept = default;
+#else
+    __native_type  _M_mutex;
+
+    __mutex_base() noexcept
+    {
+      // XXX EAGAIN, ENOMEM, EPERM, EBUSY(may), EINVAL(may)
+      __GTHREAD_MUTEX_INIT_FUNCTION(&_M_mutex);
+    }
+
+    ~__mutex_base() noexcept { __gthread_mutex_destroy(&_M_mutex); }
+#endif
+
+    __mutex_base(const __mutex_base&) = delete;
+    __mutex_base& operator=(const __mutex_base&) = delete;
+  };
+
+  /// mutex
+  class mutex : private __mutex_base
+  {
+  public:
+    typedef __native_type* 			native_handle_type;
+
+#ifdef __GTHREAD_MUTEX_INIT
+    constexpr
+#endif
+    mutex() noexcept = default;
+    ~mutex() = default;
+
+    mutex(const mutex&) = delete;
+    mutex& operator=(const mutex&) = delete;
+
+    void
+    lock()
+    {
+      int __e = __gthread_mutex_lock(&_M_mutex);
+
+      // EINVAL, EAGAIN, EBUSY, EINVAL, EDEADLK(may)
+      if (__e)
+	__throw_system_error(__e);
+    }
+
+    bool
+    try_lock() noexcept
+    {
+      // XXX EINVAL, EAGAIN, EBUSY
+      return !__gthread_mutex_trylock(&_M_mutex);
+    }
+
+    void
+    unlock()
+    {
+      // XXX EINVAL, EAGAIN, EPERM
+      __gthread_mutex_unlock(&_M_mutex);
+    }
+
+    native_handle_type
+    native_handle()
+    { return &_M_mutex; }
+  };
+
+#endif // _GLIBCXX_HAS_GTHREADS
+
+  /// Do not acquire ownership of the mutex.
+  struct defer_lock_t { };
+
+  /// Try to acquire ownership of the mutex without blocking.
+  struct try_to_lock_t { };
+
+  /// Assume the calling thread has already obtained mutex ownership
+  /// and manage it.
+  struct adopt_lock_t { };
+
+  constexpr defer_lock_t	defer_lock { };
+  constexpr try_to_lock_t	try_to_lock { };
+  constexpr adopt_lock_t	adopt_lock { };
+
+  /// @brief  Scoped lock idiom.
+  // Acquire the mutex here with a constructor call, then release with
+  // the destructor call in accordance with RAII style.
+  template<typename _Mutex>
+    class lock_guard
+    {
+    public:
+      typedef _Mutex mutex_type;
+
+      explicit lock_guard(mutex_type& __m) : _M_device(__m)
+      { _M_device.lock(); }
+
+      lock_guard(mutex_type& __m, adopt_lock_t) : _M_device(__m)
+      { } // calling thread owns mutex
+
+      ~lock_guard()
+      { _M_device.unlock(); }
+
+      lock_guard(const lock_guard&) = delete;
+      lock_guard& operator=(const lock_guard&) = delete;
+
+    private:
+      mutex_type&  _M_device;
+    };
+
+  /// unique_lock
+  template<typename _Mutex>
+    class unique_lock
+    {
+    public:
+      typedef _Mutex mutex_type;
+
+      unique_lock() noexcept
+      : _M_device(0), _M_owns(false)
+      { }
+
+      explicit unique_lock(mutex_type& __m)
+      : _M_device(std::__addressof(__m)), _M_owns(false)
+      {
+	lock();
+	_M_owns = true;
+      }
+
+      unique_lock(mutex_type& __m, defer_lock_t) noexcept
+      : _M_device(std::__addressof(__m)), _M_owns(false)
+      { }
+
+      unique_lock(mutex_type& __m, try_to_lock_t)
+      : _M_device(std::__addressof(__m)), _M_owns(_M_device->try_lock())
+      { }
+
+      unique_lock(mutex_type& __m, adopt_lock_t)
+      : _M_device(std::__addressof(__m)), _M_owns(true)
+      {
+	// XXX calling thread owns mutex
+      }
+
+      template<typename _Clock, typename _Duration>
+	unique_lock(mutex_type& __m,
+		    const chrono::time_point<_Clock, _Duration>& __atime)
+	: _M_device(std::__addressof(__m)),
+	  _M_owns(_M_device->try_lock_until(__atime))
+	{ }
+
+      template<typename _Rep, typename _Period>
+	unique_lock(mutex_type& __m,
+		    const chrono::duration<_Rep, _Period>& __rtime)
+	: _M_device(std::__addressof(__m)),
+	  _M_owns(_M_device->try_lock_for(__rtime))
+	{ }
+
+      ~unique_lock()
+      {
+	if (_M_owns)
+	  unlock();
+      }
+
+      unique_lock(const unique_lock&) = delete;
+      unique_lock& operator=(const unique_lock&) = delete;
+
+      unique_lock(unique_lock&& __u) noexcept
+      : _M_device(__u._M_device), _M_owns(__u._M_owns)
+      {
+	__u._M_device = 0;
+	__u._M_owns = false;
+      }
+
+      unique_lock& operator=(unique_lock&& __u) noexcept
+      {
+	if(_M_owns)
+	  unlock();
+
+	unique_lock(std::move(__u)).swap(*this);
+
+	__u._M_device = 0;
+	__u._M_owns = false;
+
+	return *this;
+      }
+
+      void
+      lock()
+      {
+	if (!_M_device)
+	  __throw_system_error(int(errc::operation_not_permitted));
+	else if (_M_owns)
+	  __throw_system_error(int(errc::resource_deadlock_would_occur));
+	else
+	  {
+	    _M_device->lock();
+	    _M_owns = true;
+	  }
+      }
+
+      bool
+      try_lock()
+      {
+	if (!_M_device)
+	  __throw_system_error(int(errc::operation_not_permitted));
+	else if (_M_owns)
+	  __throw_system_error(int(errc::resource_deadlock_would_occur));
+	else
+	  {
+	    _M_owns = _M_device->try_lock();
+	    return _M_owns;
+	  }
+      }
+
+      template<typename _Clock, typename _Duration>
+	bool
+	try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime)
+	{
+	  if (!_M_device)
+	    __throw_system_error(int(errc::operation_not_permitted));
+	  else if (_M_owns)
+	    __throw_system_error(int(errc::resource_deadlock_would_occur));
+	  else
+	    {
+	      _M_owns = _M_device->try_lock_until(__atime);
+	      return _M_owns;
+	    }
+	}
+
+      template<typename _Rep, typename _Period>
+	bool
+	try_lock_for(const chrono::duration<_Rep, _Period>& __rtime)
+	{
+	  if (!_M_device)
+	    __throw_system_error(int(errc::operation_not_permitted));
+	  else if (_M_owns)
+	    __throw_system_error(int(errc::resource_deadlock_would_occur));
+	  else
+	    {
+	      _M_owns = _M_device->try_lock_for(__rtime);
+	      return _M_owns;
+	    }
+	 }
+
+      void
+      unlock()
+      {
+	if (!_M_owns)
+	  __throw_system_error(int(errc::operation_not_permitted));
+	else if (_M_device)
+	  {
+	    _M_device->unlock();
+	    _M_owns = false;
+	  }
+      }
+
+      void
+      swap(unique_lock& __u) noexcept
+      {
+	std::swap(_M_device, __u._M_device);
+	std::swap(_M_owns, __u._M_owns);
+      }
+
+      mutex_type*
+      release() noexcept
+      {
+	mutex_type* __ret = _M_device;
+	_M_device = 0;
+	_M_owns = false;
+	return __ret;
+      }
+
+      bool
+      owns_lock() const noexcept
+      { return _M_owns; }
+
+      explicit operator bool() const noexcept
+      { return owns_lock(); }
+
+      mutex_type*
+      mutex() const noexcept
+      { return _M_device; }
+
+    private:
+      mutex_type*	_M_device;
+      bool		_M_owns; // XXX use atomic_bool
+    };
+
+  /// Swap overload for unique_lock objects.
+  template<typename _Mutex>
+    inline void
+    swap(unique_lock<_Mutex>& __x, unique_lock<_Mutex>& __y) noexcept
+    { __x.swap(__y); }
+
+  // @} group mutexes
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
+#endif // _GLIBCXX_USE_C99_STDINT_TR1
+
+#endif // C++11
+
+#endif // _GLIBCXX_MUTEX_H
diff --git a/libstdc++-v3/include/std/condition_variable b/libstdc++-v3/include/std/condition_variable
index fbed043..4714774 100644
--- a/libstdc++-v3/include/std/condition_variable
+++ b/libstdc++-v3/include/std/condition_variable
@@ -36,7 +36,7 @@
 #else
 
 #include <chrono>
-#include <mutex>
+#include <bits/mutex.h>
 #include <ext/concurrence.h>
 #include <bits/alloc_traits.h>
 #include <bits/allocator.h>
diff --git a/libstdc++-v3/include/std/mutex b/libstdc++-v3/include/std/mutex
index fbf1740..47141d9 100644
--- a/libstdc++-v3/include/std/mutex
+++ b/libstdc++-v3/include/std/mutex
@@ -41,9 +41,11 @@
 #include <type_traits>
 #include <functional>
 #include <system_error>
-#include <bits/functexcept.h>
-#include <bits/gthr.h>
-#include <bits/move.h> // for std::swap
+#include <bits/mutex.h>
+#if ! _GTHREAD_USE_MUTEX_TIMEDLOCK
+# include <condition_variable>
+# include <thread>
+#endif
 
 #ifdef _GLIBCXX_USE_C99_STDINT_TR1
 
@@ -51,32 +53,12 @@ namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
+  /**
+   * @ingroup mutexes
+   * @{
+   */
+
 #ifdef _GLIBCXX_HAS_GTHREADS
-  // Common base class for std::mutex and std::timed_mutex
-  class __mutex_base
-  {
-  protected:
-    typedef __gthread_mutex_t			__native_type;
-
-#ifdef __GTHREAD_MUTEX_INIT
-    __native_type  _M_mutex = __GTHREAD_MUTEX_INIT;
-
-    constexpr __mutex_base() noexcept = default;
-#else
-    __native_type  _M_mutex;
-
-    __mutex_base() noexcept
-    {
-      // XXX EAGAIN, ENOMEM, EPERM, EBUSY(may), EINVAL(may)
-      __GTHREAD_MUTEX_INIT_FUNCTION(&_M_mutex);
-    }
-
-    ~__mutex_base() noexcept { __gthread_mutex_destroy(&_M_mutex); }
-#endif
-
-    __mutex_base(const __mutex_base&) = delete;
-    __mutex_base& operator=(const __mutex_base&) = delete;
-  };
 
   // Common base class for std::recursive_mutex and std::recursive_timed_mutex
   class __recursive_mutex_base
@@ -105,58 +87,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #endif
   };
 
-  /**
-   * @defgroup mutexes Mutexes
-   * @ingroup concurrency
-   *
-   * Classes for mutex support.
-   * @{
-   */
-
-  /// mutex
-  class mutex : private __mutex_base
-  {
-  public:
-    typedef __native_type* 			native_handle_type;
-
-#ifdef __GTHREAD_MUTEX_INIT
-    constexpr
-#endif
-    mutex() noexcept = default;
-    ~mutex() = default;
-
-    mutex(const mutex&) = delete;
-    mutex& operator=(const mutex&) = delete;
-
-    void
-    lock()
-    {
-      int __e = __gthread_mutex_lock(&_M_mutex);
-
-      // EINVAL, EAGAIN, EBUSY, EINVAL, EDEADLK(may)
-      if (__e)
-	__throw_system_error(__e);
-    }
-
-    bool
-    try_lock() noexcept
-    {
-      // XXX EINVAL, EAGAIN, EBUSY
-      return !__gthread_mutex_trylock(&_M_mutex);
-    }
-
-    void
-    unlock()
-    {
-      // XXX EINVAL, EAGAIN, EPERM
-      __gthread_mutex_unlock(&_M_mutex);
-    }
-
-    native_handle_type
-    native_handle()
-    { return &_M_mutex; }
-  };
-
   /// recursive_mutex
   class recursive_mutex : private __recursive_mutex_base
   {
@@ -359,231 +289,178 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _M_timedlock(const __gthread_time_t& __ts)
       { return !__gthread_recursive_mutex_timedlock(&_M_mutex, &__ts); }
   };
+
+#else // !_GTHREAD_USE_MUTEX_TIMEDLOCK
+
+  /// timed_mutex
+  class timed_mutex
+  {
+    mutex		_M_mut;
+    condition_variable	_M_cv;
+    bool		_M_locked = false;
+
+  public:
+
+    timed_mutex() = default;
+    ~timed_mutex() { _GLIBCXX_DEBUG_ASSERT( !_M_locked ); }
+
+    timed_mutex(const timed_mutex&) = delete;
+    timed_mutex& operator=(const timed_mutex&) = delete;
+
+    void
+    lock()
+    {
+      unique_lock<mutex> __lk(_M_mut);
+      _M_cv.wait(__lk, [&]{ return !_M_locked; });
+      _M_locked = true;
+    }
+
+    bool
+    try_lock()
+    {
+      lock_guard<mutex> __lk(_M_mut);
+      if (_M_locked)
+	return false;
+      _M_locked = true;
+      return true;
+    }
+
+    template<typename _Rep, typename _Period>
+      bool
+      try_lock_for(const chrono::duration<_Rep, _Period>& __rtime)
+      {
+	unique_lock<mutex> __lk(_M_mut);
+	if (!_M_cv.wait_for(__lk, __rtime, [&]{ return !_M_locked; }))
+	  return false;
+	_M_locked = true;
+	return true;
+      }
+
+    template<typename _Clock, typename _Duration>
+      bool
+      try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime)
+      {
+	unique_lock<mutex> __lk(_M_mut);
+	if (!_M_cv.wait_until(__lk, __atime, [&]{ return !_M_locked; }))
+	  return false;
+	_M_locked = true;
+	return true;
+      }
+
+    void
+    unlock()
+    {
+      lock_guard<mutex> __lk(_M_mut);
+      _GLIBCXX_DEBUG_ASSERT( _M_locked );
+      _M_locked = false;
+      _M_cv.notify_one();
+    }
+  };
+
+  /// recursive_timed_mutex
+  class recursive_timed_mutex
+  {
+    mutex		_M_mut;
+    condition_variable	_M_cv;
+    thread::id		_M_owner;
+    unsigned		_M_count = 0;
+
+    // Predicate type that tests whether the current thread can lock a mutex.
+    struct _Can_lock
+    {
+      _Can_lock(const recursive_timed_mutex* __mx)
+      : _M_mx(__mx), _M_caller(this_thread::get_id()) { }
+
+      // Returns true if the mutex is unlocked or is locked by _M_caller.
+      bool
+      operator()() const noexcept
+      { return _M_mx->_M_count == 0 || _M_mx->_M_owner == _M_caller; }
+
+      const recursive_timed_mutex* _M_mx;
+      thread::id _M_caller;
+    };
+
+  public:
+
+    recursive_timed_mutex() = default;
+    ~recursive_timed_mutex() { _GLIBCXX_DEBUG_ASSERT( _M_count == 0 ); }
+
+    recursive_timed_mutex(const recursive_timed_mutex&) = delete;
+    recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete;
+
+    void
+    lock()
+    {
+      _Can_lock __can_lock{this};
+      unique_lock<mutex> __lk(_M_mut);
+      _M_cv.wait(__lk, __can_lock);
+      if (_M_count == -1u)
+	__throw_system_error(EAGAIN); // [thread.timedmutex.recursive]/3
+      _M_owner = __id;
+      ++_M_count;
+    }
+
+    bool
+    try_lock()
+    {
+      _Can_lock __can_lock{this};
+      lock_guard<mutex> __lk(_M_mut);
+      if (!__can_lock())
+	return false;
+      if (_M_count == -1u)
+	return false;
+      _M_owner = __id;
+      ++_M_count;
+      return true;
+    }
+
+    template<typename _Rep, typename _Period>
+      bool
+      try_lock_for(const chrono::duration<_Rep, _Period>& __rtime)
+      {
+	_Can_lock __can_lock{this};
+	unique_lock<mutex> __lk(_M_mut);
+	if (!_M_cv.wait_for(__lk, __rtime, __can_lock);
+	  return false;
+	if (_M_count == -1u)
+	  return false;
+	_M_owner = __id;
+	++_M_count;
+	return true;
+      }
+
+    template<typename _Clock, typename _Duration>
+      bool
+      try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime)
+      {
+	_Can_lock __can_lock{this};
+	unique_lock<mutex> __lk(_M_mut);
+	if (!_M_cv.wait_until(__lk, __atime, __can_lock);
+	  return false;
+	if (_M_count == -1u)
+	  return false;
+	_M_owner = __id;
+	++_M_count;
+	return true;
+      }
+
+    void
+    unlock()
+    {
+      lock_guard<mutex> __lk(_M_mut);
+      _GLIBCXX_DEBUG_ASSERT( _M_owner == this_thread::get_id() );
+      _GLIBCXX_DEBUG_ASSERT( _M_count > 0 );
+      if (--_M_count == 0)
+	{
+	  _M_owner = {};
+	  _M_cv.notify_one();
+	}
+    }
+  };
+
 #endif
 #endif // _GLIBCXX_HAS_GTHREADS
 
-  /// Do not acquire ownership of the mutex.
-  struct defer_lock_t { };
-
-  /// Try to acquire ownership of the mutex without blocking.
-  struct try_to_lock_t { };
-
-  /// Assume the calling thread has already obtained mutex ownership
-  /// and manage it.
-  struct adopt_lock_t { };
-
-  constexpr defer_lock_t	defer_lock { };
-  constexpr try_to_lock_t	try_to_lock { };
-  constexpr adopt_lock_t	adopt_lock { };
-
-  /// @brief  Scoped lock idiom.
-  // Acquire the mutex here with a constructor call, then release with
-  // the destructor call in accordance with RAII style.
-  template<typename _Mutex>
-    class lock_guard
-    {
-    public:
-      typedef _Mutex mutex_type;
-
-      explicit lock_guard(mutex_type& __m) : _M_device(__m)
-      { _M_device.lock(); }
-
-      lock_guard(mutex_type& __m, adopt_lock_t) : _M_device(__m)
-      { } // calling thread owns mutex
-
-      ~lock_guard()
-      { _M_device.unlock(); }
-
-      lock_guard(const lock_guard&) = delete;
-      lock_guard& operator=(const lock_guard&) = delete;
-
-    private:
-      mutex_type&  _M_device;
-    };
-
-  /// unique_lock
-  template<typename _Mutex>
-    class unique_lock
-    {
-    public:
-      typedef _Mutex mutex_type;
-
-      unique_lock() noexcept
-      : _M_device(0), _M_owns(false)
-      { }
-
-      explicit unique_lock(mutex_type& __m)
-      : _M_device(std::__addressof(__m)), _M_owns(false)
-      {
-	lock();
-	_M_owns = true;
-      }
-
-      unique_lock(mutex_type& __m, defer_lock_t) noexcept
-      : _M_device(std::__addressof(__m)), _M_owns(false)
-      { }
-
-      unique_lock(mutex_type& __m, try_to_lock_t)
-      : _M_device(std::__addressof(__m)), _M_owns(_M_device->try_lock())
-      { }
-
-      unique_lock(mutex_type& __m, adopt_lock_t)
-      : _M_device(std::__addressof(__m)), _M_owns(true)
-      {
-	// XXX calling thread owns mutex
-      }
-
-      template<typename _Clock, typename _Duration>
-	unique_lock(mutex_type& __m,
-		    const chrono::time_point<_Clock, _Duration>& __atime)
-	: _M_device(std::__addressof(__m)),
-	  _M_owns(_M_device->try_lock_until(__atime))
-	{ }
-
-      template<typename _Rep, typename _Period>
-	unique_lock(mutex_type& __m,
-		    const chrono::duration<_Rep, _Period>& __rtime)
-	: _M_device(std::__addressof(__m)),
-	  _M_owns(_M_device->try_lock_for(__rtime))
-	{ }
-
-      ~unique_lock()
-      {
-	if (_M_owns)
-	  unlock();
-      }
-
-      unique_lock(const unique_lock&) = delete;
-      unique_lock& operator=(const unique_lock&) = delete;
-
-      unique_lock(unique_lock&& __u) noexcept
-      : _M_device(__u._M_device), _M_owns(__u._M_owns)
-      {
-	__u._M_device = 0;
-	__u._M_owns = false;
-      }
-
-      unique_lock& operator=(unique_lock&& __u) noexcept
-      {
-	if(_M_owns)
-	  unlock();
-
-	unique_lock(std::move(__u)).swap(*this);
-
-	__u._M_device = 0;
-	__u._M_owns = false;
-
-	return *this;
-      }
-
-      void
-      lock()
-      {
-	if (!_M_device)
-	  __throw_system_error(int(errc::operation_not_permitted));
-	else if (_M_owns)
-	  __throw_system_error(int(errc::resource_deadlock_would_occur));
-	else
-	  {
-	    _M_device->lock();
-	    _M_owns = true;
-	  }
-      }
-
-      bool
-      try_lock()
-      {
-	if (!_M_device)
-	  __throw_system_error(int(errc::operation_not_permitted));
-	else if (_M_owns)
-	  __throw_system_error(int(errc::resource_deadlock_would_occur));
-	else
-	  {
-	    _M_owns = _M_device->try_lock();
-	    return _M_owns;
-	  }
-      }
-
-      template<typename _Clock, typename _Duration>
-	bool
-	try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime)
-	{
-	  if (!_M_device)
-	    __throw_system_error(int(errc::operation_not_permitted));
-	  else if (_M_owns)
-	    __throw_system_error(int(errc::resource_deadlock_would_occur));
-	  else
-	    {
-	      _M_owns = _M_device->try_lock_until(__atime);
-	      return _M_owns;
-	    }
-	}
-
-      template<typename _Rep, typename _Period>
-	bool
-	try_lock_for(const chrono::duration<_Rep, _Period>& __rtime)
-	{
-	  if (!_M_device)
-	    __throw_system_error(int(errc::operation_not_permitted));
-	  else if (_M_owns)
-	    __throw_system_error(int(errc::resource_deadlock_would_occur));
-	  else
-	    {
-	      _M_owns = _M_device->try_lock_for(__rtime);
-	      return _M_owns;
-	    }
-	 }
-
-      void
-      unlock()
-      {
-	if (!_M_owns)
-	  __throw_system_error(int(errc::operation_not_permitted));
-	else if (_M_device)
-	  {
-	    _M_device->unlock();
-	    _M_owns = false;
-	  }
-      }
-
-      void
-      swap(unique_lock& __u) noexcept
-      {
-	std::swap(_M_device, __u._M_device);
-	std::swap(_M_owns, __u._M_owns);
-      }
-
-      mutex_type*
-      release() noexcept
-      {
-	mutex_type* __ret = _M_device;
-	_M_device = 0;
-	_M_owns = false;
-	return __ret;
-      }
-
-      bool
-      owns_lock() const noexcept
-      { return _M_owns; }
-
-      explicit operator bool() const noexcept
-      { return owns_lock(); }
-
-      mutex_type*
-      mutex() const noexcept
-      { return _M_device; }
-
-    private:
-      mutex_type*	_M_device;
-      bool		_M_owns; // XXX use atomic_bool
-    };
-
-  /// Swap overload for unique_lock objects.
-  template<typename _Mutex>
-    inline void
-    swap(unique_lock<_Mutex>& __x, unique_lock<_Mutex>& __y) noexcept
-    { __x.swap(__y); }
-
   template<typename _Lock>
     inline unique_lock<_Lock>
     __try_to_lock(_Lock& __l)
diff --git a/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/cons/1.cc b/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/cons/1.cc
index a3e1b34..6e4c7f5 100644
--- a/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/cons/1.cc
+++ b/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/cons/1.cc
@@ -3,7 +3,6 @@
 // { dg-options " -std=gnu++11 -pthreads" { target *-*-solaris* } }
 // { dg-options " -std=gnu++11 " { target *-*-cygwin *-*-rtems* *-*-darwin* } }
 // { dg-require-cstdint "" }
-// { dg-require-gthreads-timed "" }
 
 // Copyright (C) 2008-2015 Free Software Foundation, Inc.
 //
diff --git a/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/cons/assign_neg.cc b/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/cons/assign_neg.cc
index 6e50632..62264fe 100644
--- a/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/cons/assign_neg.cc
+++ b/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/cons/assign_neg.cc
@@ -1,7 +1,6 @@
 // { dg-do compile }
 // { dg-options "-std=gnu++11" }
 // { dg-require-cstdint "" }
-// { dg-require-gthreads-timed "" }
 
 // Copyright (C) 2008-2015 Free Software Foundation, Inc.
 //
diff --git a/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/cons/copy_neg.cc b/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/cons/copy_neg.cc
index 480c1cc..4f2c3cc 100644
--- a/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/cons/copy_neg.cc
+++ b/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/cons/copy_neg.cc
@@ -1,7 +1,6 @@
 // { dg-do compile }
 // { dg-options "-std=gnu++11" }
 // { dg-require-cstdint "" }
-// { dg-require-gthreads-timed "" }
 
 // Copyright (C) 2008-2015 Free Software Foundation, Inc.
 //
diff --git a/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/dest/destructor_locked.cc b/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/dest/destructor_locked.cc
index f823667..e06caec 100644
--- a/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/dest/destructor_locked.cc
+++ b/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/dest/destructor_locked.cc
@@ -3,7 +3,6 @@
 // { dg-options " -std=gnu++11 -pthreads" { target *-*-solaris* } }
 // { dg-options " -std=gnu++11 " { target *-*-cygwin *-*-rtems* *-*-darwin* } }
 // { dg-require-cstdint "" }
-// { dg-require-gthreads-timed "" }
 
 // Copyright (C) 2008-2015 Free Software Foundation, Inc.
 //
diff --git a/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/lock/1.cc b/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/lock/1.cc
index 0b5d3aa..104f0a9 100644
--- a/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/lock/1.cc
+++ b/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/lock/1.cc
@@ -3,7 +3,6 @@
 // { dg-options " -std=gnu++11 -pthreads" { target *-*-solaris* } }
 // { dg-options " -std=gnu++11 " { target *-*-cygwin *-*-rtems* *-*-darwin* } }
 // { dg-require-cstdint "" }
-// { dg-require-gthreads-timed "" }
 
 // Copyright (C) 2008-2015 Free Software Foundation, Inc.
 //
diff --git a/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/lock/2.cc b/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/lock/2.cc
index c2b56ea..d4528b5 100644
--- a/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/lock/2.cc
+++ b/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/lock/2.cc
@@ -3,7 +3,6 @@
 // { dg-options " -std=gnu++11 -pthreads" { target *-*-solaris* } }
 // { dg-options " -std=gnu++11 " { target *-*-cygwin *-*-rtems* *-*-darwin* } }
 // { dg-require-cstdint "" }
-// { dg-require-gthreads-timed "" }
 
 // Copyright (C) 2008-2015 Free Software Foundation, Inc.
 //
diff --git a/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/try_lock/1.cc b/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/try_lock/1.cc
index 3afc43a..f56afc8 100644
--- a/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/try_lock/1.cc
+++ b/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/try_lock/1.cc
@@ -3,7 +3,6 @@
 // { dg-options " -std=gnu++11 -pthreads" { target *-*-solaris* } }
 // { dg-options " -std=gnu++11 " { target *-*-cygwin *-*-rtems* *-*-darwin* } }
 // { dg-require-cstdint "" }
-// { dg-require-gthreads-timed "" }
 
 // Copyright (C) 2008-2015 Free Software Foundation, Inc.
 //
diff --git a/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/try_lock/2.cc b/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/try_lock/2.cc
index 335fc8f..5ec212b 100644
--- a/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/try_lock/2.cc
+++ b/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/try_lock/2.cc
@@ -3,7 +3,6 @@
 // { dg-options "-std=gnu++11 -pthreads" { target *-*-solaris* } }
 // { dg-options "-std=gnu++11 " { target *-*-cygwin *-*-rtems* *-*-darwin* } }
 // { dg-require-cstdint "" }
-// { dg-require-gthreads-timed "" }
 
 // Copyright (C) 2008-2015 Free Software Foundation, Inc.
 //
diff --git a/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/try_lock_for/1.cc b/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/try_lock_for/1.cc
index 043e4c2..c17525f 100644
--- a/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/try_lock_for/1.cc
+++ b/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/try_lock_for/1.cc
@@ -3,7 +3,6 @@
 // { dg-options " -std=gnu++11 -pthreads" { target *-*-solaris* } }
 // { dg-options " -std=gnu++11 " { target *-*-cygwin *-*-rtems* *-*-darwin* } }
 // { dg-require-cstdint "" }
-// { dg-require-gthreads-timed "" }
 
 // Copyright (C) 2008-2015 Free Software Foundation, Inc.
 //
diff --git a/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/try_lock_for/2.cc b/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/try_lock_for/2.cc
index 8eb3e4b..e9bc371 100644
--- a/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/try_lock_for/2.cc
+++ b/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/try_lock_for/2.cc
@@ -3,7 +3,6 @@
 // { dg-options " -std=gnu++11 -pthreads" { target *-*-solaris* } }
 // { dg-options " -std=gnu++11 " { target *-*-cygwin *-*-rtems* *-*-darwin* } }
 // { dg-require-cstdint "" }
-// { dg-require-gthreads-timed "" }
 
 // Copyright (C) 2008-2015 Free Software Foundation, Inc.
 //
diff --git a/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/try_lock_for/3.cc b/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/try_lock_for/3.cc
index 33bdcca..33ec4f2 100644
--- a/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/try_lock_for/3.cc
+++ b/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/try_lock_for/3.cc
@@ -3,7 +3,6 @@
 // { dg-options " -std=gnu++11 -pthreads" { target *-*-solaris* } }
 // { dg-options " -std=gnu++11 " { target *-*-cygwin *-*-rtems* *-*-darwin* } }
 // { dg-require-cstdint "" }
-// { dg-require-gthreads-timed "" }
 
 // Copyright (C) 2008-2015 Free Software Foundation, Inc.
 //
diff --git a/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/try_lock_until/1.cc b/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/try_lock_until/1.cc
index 3afc43a..f56afc8 100644
--- a/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/try_lock_until/1.cc
+++ b/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/try_lock_until/1.cc
@@ -3,7 +3,6 @@
 // { dg-options " -std=gnu++11 -pthreads" { target *-*-solaris* } }
 // { dg-options " -std=gnu++11 " { target *-*-cygwin *-*-rtems* *-*-darwin* } }
 // { dg-require-cstdint "" }
-// { dg-require-gthreads-timed "" }
 
 // Copyright (C) 2008-2015 Free Software Foundation, Inc.
 //
diff --git a/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/try_lock_until/2.cc b/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/try_lock_until/2.cc
index 6269da0..367134a 100644
--- a/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/try_lock_until/2.cc
+++ b/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/try_lock_until/2.cc
@@ -3,7 +3,6 @@
 // { dg-options " -std=gnu++11 -pthreads" { target *-*-solaris* } }
 // { dg-options " -std=gnu++11 " { target *-*-cygwin *-*-rtems* *-*-darwin* } }
 // { dg-require-cstdint "" }
-// { dg-require-gthreads-timed "" }
 
 // Copyright (C) 2008-2015 Free Software Foundation, Inc.
 //
diff --git a/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/unlock/1.cc b/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/unlock/1.cc
index 4477fbf..44e0b15 100644
--- a/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/unlock/1.cc
+++ b/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/unlock/1.cc
@@ -3,7 +3,6 @@
 // { dg-options " -std=gnu++11 -pthreads" { target *-*-solaris* } }
 // { dg-options " -std=gnu++11 " { target *-*-cygwin *-*-rtems* *-*-darwin* } }
 // { dg-require-cstdint "" }
-// { dg-require-gthreads-timed "" }
 
 // Copyright (C) 2008-2015 Free Software Foundation, Inc.
 //
diff --git a/libstdc++-v3/testsuite/30_threads/timed_mutex/cons/1.cc b/libstdc++-v3/testsuite/30_threads/timed_mutex/cons/1.cc
index 56e489b..d6664fb 100644
--- a/libstdc++-v3/testsuite/30_threads/timed_mutex/cons/1.cc
+++ b/libstdc++-v3/testsuite/30_threads/timed_mutex/cons/1.cc
@@ -3,7 +3,6 @@
 // { dg-options " -std=gnu++11 -pthreads" { target *-*-solaris* } }
 // { dg-options " -std=gnu++11 " { target *-*-cygwin *-*-rtems* *-*-darwin* } }
 // { dg-require-cstdint "" }
-// { dg-require-gthreads-timed "" }
 
 // Copyright (C) 2008-2015 Free Software Foundation, Inc.
 //
diff --git a/libstdc++-v3/testsuite/30_threads/timed_mutex/cons/assign_neg.cc b/libstdc++-v3/testsuite/30_threads/timed_mutex/cons/assign_neg.cc
index d953a4c..c6ba402 100644
--- a/libstdc++-v3/testsuite/30_threads/timed_mutex/cons/assign_neg.cc
+++ b/libstdc++-v3/testsuite/30_threads/timed_mutex/cons/assign_neg.cc
@@ -1,7 +1,6 @@
 // { dg-do compile }
 // { dg-options "-std=gnu++11" }
 // { dg-require-cstdint "" }
-// { dg-require-gthreads-timed "" }
 
 // Copyright (C) 2008-2015 Free Software Foundation, Inc.
 //
diff --git a/libstdc++-v3/testsuite/30_threads/timed_mutex/cons/copy_neg.cc b/libstdc++-v3/testsuite/30_threads/timed_mutex/cons/copy_neg.cc
index 1acb231..1874b04 100644
--- a/libstdc++-v3/testsuite/30_threads/timed_mutex/cons/copy_neg.cc
+++ b/libstdc++-v3/testsuite/30_threads/timed_mutex/cons/copy_neg.cc
@@ -1,7 +1,6 @@
 // { dg-do compile }
 // { dg-options "-std=gnu++11" }
 // { dg-require-cstdint "" }
-// { dg-require-gthreads-timed "" }
 
 // Copyright (C) 2008-2015 Free Software Foundation, Inc.
 //
diff --git a/libstdc++-v3/testsuite/30_threads/timed_mutex/dest/destructor_locked.cc b/libstdc++-v3/testsuite/30_threads/timed_mutex/dest/destructor_locked.cc
index 180174c..5e7d273 100644
--- a/libstdc++-v3/testsuite/30_threads/timed_mutex/dest/destructor_locked.cc
+++ b/libstdc++-v3/testsuite/30_threads/timed_mutex/dest/destructor_locked.cc
@@ -3,7 +3,6 @@
 // { dg-options " -std=gnu++11 -pthreads" { target *-*-solaris* } }
 // { dg-options " -std=gnu++11 " { target *-*-cygwin *-*-rtems* *-*-darwin* } }
 // { dg-require-cstdint "" }
-// { dg-require-gthreads-timed "" }
 
 // Copyright (C) 2008-2015 Free Software Foundation, Inc.
 //
diff --git a/libstdc++-v3/testsuite/30_threads/timed_mutex/lock/1.cc b/libstdc++-v3/testsuite/30_threads/timed_mutex/lock/1.cc
index 5eb4bdd..26d4c78 100644
--- a/libstdc++-v3/testsuite/30_threads/timed_mutex/lock/1.cc
+++ b/libstdc++-v3/testsuite/30_threads/timed_mutex/lock/1.cc
@@ -3,7 +3,6 @@
 // { dg-options " -std=gnu++11 -pthreads" { target *-*-solaris* } }
 // { dg-options " -std=gnu++11 " { target *-*-cygwin *-*-rtems* *-*-darwin* } }
 // { dg-require-cstdint "" }
-// { dg-require-gthreads-timed "" }
 
 // Copyright (C) 2008-2015 Free Software Foundation, Inc.
 //
diff --git a/libstdc++-v3/testsuite/30_threads/timed_mutex/requirements/standard_layout.cc b/libstdc++-v3/testsuite/30_threads/timed_mutex/requirements/standard_layout.cc
index f94228e..e053aeb 100644
--- a/libstdc++-v3/testsuite/30_threads/timed_mutex/requirements/standard_layout.cc
+++ b/libstdc++-v3/testsuite/30_threads/timed_mutex/requirements/standard_layout.cc
@@ -1,7 +1,6 @@
 // { dg-do compile }
 // { dg-options "-std=gnu++11" }
 // { dg-require-cstdint "" }
-// { dg-require-gthreads-timed "" }
 
 // Copyright (C) 2009-2015 Free Software Foundation, Inc.
 //
diff --git a/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock/1.cc b/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock/1.cc
index 7766eb6..029f779 100644
--- a/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock/1.cc
+++ b/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock/1.cc
@@ -3,7 +3,6 @@
 // { dg-options " -std=gnu++11 -pthreads" { target *-*-solaris* } }
 // { dg-options " -std=gnu++11 " { target *-*-cygwin *-*-rtems* *-*-darwin* } }
 // { dg-require-cstdint "" }
-// { dg-require-gthreads-timed "" }
 
 // Copyright (C) 2008-2015 Free Software Foundation, Inc.
 //
diff --git a/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock/2.cc b/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock/2.cc
index f99e442..5dc3316 100644
--- a/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock/2.cc
+++ b/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock/2.cc
@@ -3,7 +3,6 @@
 // { dg-options " -std=gnu++11 -pthreads" { target *-*-solaris* } }
 // { dg-options " -std=gnu++11 " { target *-*-cygwin *-*-rtems* *-*-darwin* } }
 // { dg-require-cstdint "" }
-// { dg-require-gthreads-timed "" }
 
 // Copyright (C) 2008-2015 Free Software Foundation, Inc.
 //
diff --git a/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock_for/1.cc b/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock_for/1.cc
index 7af70c1..5791aa1 100644
--- a/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock_for/1.cc
+++ b/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock_for/1.cc
@@ -3,7 +3,6 @@
 // { dg-options " -std=gnu++11 -pthreads" { target *-*-solaris* } }
 // { dg-options " -std=gnu++11 " { target *-*-cygwin *-*-rtems* *-*-darwin* } }
 // { dg-require-cstdint "" }
-// { dg-require-gthreads-timed "" }
 
 // Copyright (C) 2008-2015 Free Software Foundation, Inc.
 //
diff --git a/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock_for/2.cc b/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock_for/2.cc
index b7936e6..8bfe85b 100644
--- a/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock_for/2.cc
+++ b/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock_for/2.cc
@@ -3,7 +3,6 @@
 // { dg-options " -std=gnu++11 -pthreads" { target *-*-solaris* } }
 // { dg-options " -std=gnu++11 " { target *-*-cygwin *-*-rtems* *-*-darwin* } }
 // { dg-require-cstdint "" }
-// { dg-require-gthreads-timed "" }
 
 // Copyright (C) 2008-2015 Free Software Foundation, Inc.
 //
diff --git a/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock_for/3.cc b/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock_for/3.cc
index 1d21edf..082e4ef 100644
--- a/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock_for/3.cc
+++ b/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock_for/3.cc
@@ -3,7 +3,6 @@
 // { dg-options " -std=gnu++11 -pthreads" { target *-*-solaris* } }
 // { dg-options " -std=gnu++11 " { target *-*-cygwin *-*-rtems* *-*-darwin* } }
 // { dg-require-cstdint "" }
-// { dg-require-gthreads-timed "" }
 
 // Copyright (C) 2008-2015 Free Software Foundation, Inc.
 //
diff --git a/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock_until/1.cc b/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock_until/1.cc
index 7766eb6..029f779 100644
--- a/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock_until/1.cc
+++ b/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock_until/1.cc
@@ -3,7 +3,6 @@
 // { dg-options " -std=gnu++11 -pthreads" { target *-*-solaris* } }
 // { dg-options " -std=gnu++11 " { target *-*-cygwin *-*-rtems* *-*-darwin* } }
 // { dg-require-cstdint "" }
-// { dg-require-gthreads-timed "" }
 
 // Copyright (C) 2008-2015 Free Software Foundation, Inc.
 //
diff --git a/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock_until/2.cc b/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock_until/2.cc
index f99e442..5dc3316 100644
--- a/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock_until/2.cc
+++ b/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock_until/2.cc
@@ -3,7 +3,6 @@
 // { dg-options " -std=gnu++11 -pthreads" { target *-*-solaris* } }
 // { dg-options " -std=gnu++11 " { target *-*-cygwin *-*-rtems* *-*-darwin* } }
 // { dg-require-cstdint "" }
-// { dg-require-gthreads-timed "" }
 
 // Copyright (C) 2008-2015 Free Software Foundation, Inc.
 //
diff --git a/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock_until/57641.cc b/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock_until/57641.cc
index 86857b3..15f9cdf 100644
--- a/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock_until/57641.cc
+++ b/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock_until/57641.cc
@@ -3,7 +3,6 @@
 // { dg-options " -std=gnu++11 -pthreads" { target *-*-solaris* } }
 // { dg-options " -std=gnu++11 " { target *-*-cygwin *-*-rtems* *-*-darwin* } }
 // { dg-require-cstdint "" }
-// { dg-require-gthreads-timed "" }
 
 // Copyright (C) 2013-2015 Free Software Foundation, Inc.
 //
diff --git a/libstdc++-v3/testsuite/30_threads/timed_mutex/unlock/1.cc b/libstdc++-v3/testsuite/30_threads/timed_mutex/unlock/1.cc
index d086bce..812e2d8 100644
--- a/libstdc++-v3/testsuite/30_threads/timed_mutex/unlock/1.cc
+++ b/libstdc++-v3/testsuite/30_threads/timed_mutex/unlock/1.cc
@@ -3,7 +3,6 @@
 // { dg-options " -std=gnu++11 -pthreads" { target *-*-solaris* } }
 // { dg-options " -std=gnu++11 " { target *-*-cygwin *-*-rtems* *-*-darwin* } }
 // { dg-require-cstdint "" }
-// { dg-require-gthreads-timed "" }
 
 // Copyright (C) 2008-2015 Free Software Foundation, Inc.
 //
diff --git a/libstdc++-v3/testsuite/30_threads/unique_lock/cons/5.cc b/libstdc++-v3/testsuite/30_threads/unique_lock/cons/5.cc
index d1fdb54..b62af9b 100644
--- a/libstdc++-v3/testsuite/30_threads/unique_lock/cons/5.cc
+++ b/libstdc++-v3/testsuite/30_threads/unique_lock/cons/5.cc
@@ -3,7 +3,6 @@
 // { dg-options " -std=gnu++11 -pthreads" { target *-*-solaris* } }
 // { dg-options " -std=gnu++11 " { target *-*-cygwin *-*-rtems* *-*-darwin* } }
 // { dg-require-cstdint "" }
-// { dg-require-gthreads-timed "" }
 
 // Copyright (C) 2008-2015 Free Software Foundation, Inc.
 //
diff --git a/libstdc++-v3/testsuite/30_threads/unique_lock/cons/6.cc b/libstdc++-v3/testsuite/30_threads/unique_lock/cons/6.cc
index f0c36cf..36b1cd6 100644
--- a/libstdc++-v3/testsuite/30_threads/unique_lock/cons/6.cc
+++ b/libstdc++-v3/testsuite/30_threads/unique_lock/cons/6.cc
@@ -3,7 +3,6 @@
 // { dg-options " -std=gnu++11 -pthreads" { target *-*-solaris* } }
 // { dg-options " -std=gnu++11 " { target *-*-cygwin *-*-rtems* *-*-darwin* } }
 // { dg-require-cstdint "" }
-// { dg-require-gthreads-timed "" }
 
 // Copyright (C) 2008-2015 Free Software Foundation, Inc.
 //
diff --git a/libstdc++-v3/testsuite/30_threads/unique_lock/locking/3.cc b/libstdc++-v3/testsuite/30_threads/unique_lock/locking/3.cc
index 568de7ad..11b4fb6 100644
--- a/libstdc++-v3/testsuite/30_threads/unique_lock/locking/3.cc
+++ b/libstdc++-v3/testsuite/30_threads/unique_lock/locking/3.cc
@@ -3,7 +3,6 @@
 // { dg-options " -std=gnu++11 -pthreads" { target *-*-solaris* } }
 // { dg-options " -std=gnu++11 " { target *-*-cygwin *-*-rtems* *-*-darwin* } }
 // { dg-require-cstdint "" }
-// { dg-require-gthreads-timed "" }
 
 // Copyright (C) 2008-2015 Free Software Foundation, Inc.
 //
diff --git a/libstdc++-v3/testsuite/30_threads/unique_lock/locking/4.cc b/libstdc++-v3/testsuite/30_threads/unique_lock/locking/4.cc
index e2e3aaa..2be15bf 100644
--- a/libstdc++-v3/testsuite/30_threads/unique_lock/locking/4.cc
+++ b/libstdc++-v3/testsuite/30_threads/unique_lock/locking/4.cc
@@ -3,7 +3,6 @@
 // { dg-options " -std=gnu++11 -pthreads" { target *-*-solaris* } }
 // { dg-options " -std=gnu++11 " { target *-*-cygwin *-*-rtems* *-*-darwin* } }
 // { dg-require-cstdint "" }
-// { dg-require-gthreads-timed "" }
 
 // Copyright (C) 2008-2015 Free Software Foundation, Inc.
 //

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]