diff mbox

N3659: add C++14's <shared_mutex>

Message ID CAH6eHdTqKG+CTETsFz9EGdkkFas0eqHYQxH6QZCVuarS7hXcLA@mail.gmail.com
State New
Headers show

Commit Message

Jonathan Wakely June 16, 2013, 4:35 p.m. UTC
This implements N3659, adding <shared_mutex> for C++14.

I used Howard's reference implementation in terms of std::mutex and
std::condition_variable. I haven't benchmarked this against using
pthread_rwlock_t, but this is more portable anyway.  We might want to
consider an alternative implementation for gthr_posix.h targets at a
later date, but I'm not planning to work on that.

        * include/std/shared_mutex: Implement N3659.
        * include/bits/c++14_warning.h: New.
        * include/Makefile.am: Add new headers.
        * include/Makefile.in: Regenerate.
        * testsuite/30_threads/shared_lock/cons/1.cc: New.
        * testsuite/30_threads/shared_lock/locking/2.cc: New.
        * testsuite/30_threads/shared_lock/cons/2.cc: New.
        * testsuite/30_threads/shared_lock/locking/3.cc: New.
        * testsuite/30_threads/shared_lock/cons/3.cc: New.
        * testsuite/30_threads/shared_lock/locking/4.cc: New.
        * testsuite/30_threads/shared_lock/cons/4.cc: New.
        * testsuite/30_threads/shared_lock/modifiers/1.cc: New.
        * testsuite/30_threads/shared_lock/cons/5.cc: New.
        * testsuite/30_threads/shared_lock/modifiers/2.cc: New.
        * testsuite/30_threads/shared_lock/cons/6.cc: New.
        * testsuite/30_threads/shared_lock/requirements/
        explicit_instantiation.cc: New.
        * testsuite/30_threads/shared_lock/locking/1.cc: New.
        * testsuite/30_threads/shared_lock/requirements/typedefs.cc: New.
        * testsuite/30_threads/shared_mutex/cons/1.cc: New.
        * testsuite/30_threads/shared_mutex/cons/assign_neg.cc: New.
        * testsuite/30_threads/shared_mutex/cons/copy_neg.cc: New.
        * testsuite/30_threads/shared_mutex/requirements/
        standard_layout.cc: New.
        * testsuite/30_threads/shared_mutex/try_lock/1.cc: New.
        * testsuite/30_threads/shared_mutex/try_lock/2.cc: New.

Tested x86_64-linux, committed to trunk.
commit ba89a96455193d329d35053f405bd5a881af74ec
Author: Jonathan Wakely <jwakely.gcc@gmail.com>
Date:   Sun Jun 16 15:36:54 2013 +0100

    	* include/std/shared_mutex: Implement N3659.
    	* include/bits/c++14_warning.h: New.
    	* include/Makefile.am: Add new headers.
    	* include/Makefile.in: Regenerate.
    	* testsuite/30_threads/shared_lock/cons/1.cc: New.
    	* testsuite/30_threads/shared_lock/locking/2.cc: New.
    	* testsuite/30_threads/shared_lock/cons/2.cc: New.
    	* testsuite/30_threads/shared_lock/locking/3.cc: New.
    	* testsuite/30_threads/shared_lock/cons/3.cc: New.
    	* testsuite/30_threads/shared_lock/locking/4.cc: New.
    	* testsuite/30_threads/shared_lock/cons/4.cc: New.
    	* testsuite/30_threads/shared_lock/modifiers/1.cc: New.
    	* testsuite/30_threads/shared_lock/cons/5.cc: New.
    	* testsuite/30_threads/shared_lock/modifiers/2.cc: New.
    	* testsuite/30_threads/shared_lock/cons/6.cc: New.
    	* testsuite/30_threads/shared_lock/requirements/
    	explicit_instantiation.cc: New.
    	* testsuite/30_threads/shared_lock/locking/1.cc: New.
    	* testsuite/30_threads/shared_lock/requirements/typedefs.cc: New.
    	* testsuite/30_threads/shared_mutex/cons/1.cc: New.
    	* testsuite/30_threads/shared_mutex/cons/assign_neg.cc: New.
    	* testsuite/30_threads/shared_mutex/cons/copy_neg.cc: New.
    	* testsuite/30_threads/shared_mutex/requirements/
    	standard_layout.cc: New.
    	* testsuite/30_threads/shared_mutex/try_lock/1.cc: New.
    	* testsuite/30_threads/shared_mutex/try_lock/2.cc: New.
diff mbox

Patch

diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index f09300b..801a885 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -58,6 +58,7 @@  std_headers = \
 	${std_srcdir}/regex \
 	${std_srcdir}/scoped_allocator \
 	${std_srcdir}/set \
+	${std_srcdir}/shared_mutex \
 	${std_srcdir}/sstream \
 	${std_srcdir}/stack \
 	${std_srcdir}/stdexcept \
@@ -87,6 +88,7 @@  bits_headers = \
 	${bits_srcdir}/basic_string.tcc \
 	${bits_srcdir}/boost_concept_check.h \
 	${bits_srcdir}/c++0x_warning.h \
+	${bits_srcdir}/c++14_warning.h \
 	${bits_srcdir}/char_traits.h \
 	${bits_srcdir}/codecvt.h \
 	${bits_srcdir}/concept_check.h \
diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in
index a090cad..995b898 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -320,6 +320,7 @@  std_headers = \
 	${std_srcdir}/regex \
 	${std_srcdir}/scoped_allocator \
 	${std_srcdir}/set \
+	${std_srcdir}/shared_mutex \
 	${std_srcdir}/sstream \
 	${std_srcdir}/stack \
 	${std_srcdir}/stdexcept \
@@ -349,6 +350,7 @@  bits_headers = \
 	${bits_srcdir}/basic_string.tcc \
 	${bits_srcdir}/boost_concept_check.h \
 	${bits_srcdir}/c++0x_warning.h \
+	${bits_srcdir}/c++14_warning.h \
 	${bits_srcdir}/char_traits.h \
 	${bits_srcdir}/codecvt.h \
 	${bits_srcdir}/concept_check.h \
diff --git a/libstdc++-v3/include/bits/c++14_warning.h b/libstdc++-v3/include/bits/c++14_warning.h
new file mode 100644
index 0000000..ff2adfa
--- /dev/null
+++ b/libstdc++-v3/include/bits/c++14_warning.h
@@ -0,0 +1,37 @@ 
+// Copyright (C) 2013 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/c++14_warning.h
+ *  This is an internal header file, included by other library headers.
+ *  Do not attempt to use it directly. @headername{iosfwd}
+ */
+
+#ifndef _CXX14_WARNING_H
+#define _CXX14_WARNING_H 1
+
+#if __cplusplus <= 201103L
+#error This file requires compiler and library support for the forthcoming \
+ISO C++ 2014 standard. This support is currently experimental, and must be \
+enabled with the -std=c++1y or -std=gnu++1y compiler options.
+#endif
+
+#endif
diff --git a/libstdc++-v3/include/std/shared_mutex b/libstdc++-v3/include/std/shared_mutex
new file mode 100644
index 0000000..f606282
--- /dev/null
+++ b/libstdc++-v3/include/std/shared_mutex
@@ -0,0 +1,434 @@ 
+// <shared_mutex> -*- C++ -*-
+
+// Copyright (C) 2013 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 include/shared_mutex
+ *  This is a Standard C++ Library header.
+ */
+
+#ifndef _GLIBCXX_SHARED_MUTEX
+#define _GLIBCXX_SHARED_MUTEX 1
+
+#pragma GCC system_header
+
+#if __cplusplus <= 201103L
+# include <bits/c++14_warning.h>
+#else
+
+#include <bits/c++config.h>
+#if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1)
+# include <mutex>
+# include <condition_variable>
+#endif
+#include <bits/functexcept.h>
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  /**
+   * @ingroup mutexes
+   * @{
+   */
+
+#if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1)
+  /// shared_mutex
+  class shared_mutex
+  {
+#if _GTHREAD_USE_MUTEX_TIMEDLOCK
+    struct _Mutex : mutex
+    {
+      typedef chrono::steady_clock 	  	__clock_t;
+
+      template <class _Rep, class _Period>
+	bool
+	try_lock_for(const chrono::duration<_Rep, _Period>& __rtime)
+	{ return __try_lock_for_impl(__rtime); }
+
+      template <class _Clock, class _Duration>
+	bool
+	try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime)
+	{
+	  chrono::time_point<_Clock, chrono::seconds> __s =
+	    chrono::time_point_cast<chrono::seconds>(__atime);
+
+	  chrono::nanoseconds __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())
+	  };
+
+	  return !__gthread_mutex_timedlock(native_handle(), &__ts);
+	}
+
+    private:
+      template<typename _Rep, typename _Period>
+	typename enable_if<
+	  ratio_less_equal<__clock_t::period, _Period>::value, bool>::type
+	__try_lock_for_impl(const chrono::duration<_Rep, _Period>& __rtime)
+	{
+	  __clock_t::time_point __atime = __clock_t::now()
+	    + chrono::duration_cast<__clock_t::duration>(__rtime);
+
+	  return try_lock_until(__atime);
+	}
+
+      template <typename _Rep, typename _Period>
+	typename enable_if<
+	  !ratio_less_equal<__clock_t::period, _Period>::value, bool>::type
+	__try_lock_for_impl(const chrono::duration<_Rep, _Period>& __rtime)
+	{
+	  __clock_t::time_point __atime = __clock_t::now()
+	    + ++chrono::duration_cast<__clock_t::duration>(__rtime);
+
+	  return try_lock_until(__atime);
+	}
+    };
+#else
+    typedef mutex _Mutex;
+#endif
+
+    // Based on Howard Hinnant's reference implementation from N2406
+
+    _Mutex		_M_mut;
+    condition_variable	_M_gate1;
+    condition_variable	_M_gate2;
+    unsigned		_M_state;
+
+    static constexpr unsigned _S_write_entered
+      = 1U << (sizeof(unsigned)*__CHAR_BIT__ - 1);
+    static constexpr unsigned _M_n_readers = ~_S_write_entered;
+
+  public:
+    shared_mutex() : _M_state(0) {}
+
+    ~shared_mutex()
+    {
+      _GLIBCXX_DEBUG_ASSERT( _M_state == 0 );
+    }
+
+    shared_mutex(const shared_mutex&) = delete;
+    shared_mutex& operator=(const shared_mutex&) = delete;
+
+    // Exclusive ownership
+
+    void
+    lock()
+    {
+      unique_lock<mutex> __lk(_M_mut);
+      while (_M_state & _S_write_entered)
+	_M_gate1.wait(__lk);
+      _M_state |= _S_write_entered;
+      while (_M_state & _M_n_readers)
+	_M_gate2.wait(__lk);
+    }
+
+    bool
+    try_lock()
+    {
+      unique_lock<mutex> __lk(_M_mut, try_to_lock);
+      if (__lk.owns_lock() && _M_state == 0)
+	{
+	  _M_state = _S_write_entered;
+	  return true;
+	}
+      return false;
+    }
+
+#if _GTHREAD_USE_MUTEX_TIMEDLOCK
+    template<typename _Rep, typename _Period>
+      bool
+      try_lock_for(const chrono::duration<_Rep, _Period>& __rel_time)
+      {
+	unique_lock<_Mutex> __lk(_M_mut, __rel_time);
+	if (__lk.owns_lock() && _M_state == 0)
+	  {
+	    _M_state = _S_write_entered;
+	    return true;
+	  }
+	return false;
+      }
+
+    template<typename _Clock, typename _Duration>
+      bool
+      try_lock_until(const chrono::time_point<_Clock, _Duration>& __abs_time)
+      {
+	unique_lock<_Mutex> __lk(_M_mut, __abs_time);
+	if (__lk.owns_lock() && _M_state == 0)
+	  {
+	    _M_state = _S_write_entered;
+	    return true;
+	  }
+	return false;
+      }
+#endif
+
+    void
+    unlock()
+    {
+      {
+	lock_guard<_Mutex> __lk(_M_mut);
+	_M_state = 0;
+      }
+      _M_gate1.notify_all();
+    }
+
+    // Shared ownership
+
+    void
+    lock_shared()
+    {
+      unique_lock<mutex> __lk(_M_mut);
+      while ((_M_state & _S_write_entered)
+	  || (_M_state & _M_n_readers) == _M_n_readers)
+	{
+	  _M_gate1.wait(__lk);
+	}
+      unsigned __num_readers = (_M_state & _M_n_readers) + 1;
+      _M_state &= ~_M_n_readers;
+      _M_state |= __num_readers;
+    }
+
+    bool
+    try_lock_shared()
+    {
+      unique_lock<_Mutex> __lk(_M_mut, try_to_lock);
+      unsigned __num_readers = _M_state & _M_n_readers;
+      if (__lk.owns_lock() && !(_M_state & _S_write_entered)
+	  && __num_readers != _M_n_readers)
+	{
+	  ++__num_readers;
+	  _M_state &= ~_M_n_readers;
+	  _M_state |= __num_readers;
+	  return true;
+	}
+      return false;
+    }
+
+#if _GTHREAD_USE_MUTEX_TIMEDLOCK
+    template<typename _Rep, typename _Period>
+      bool
+      try_lock_shared_for(const chrono::duration<_Rep, _Period>& __rel_time)
+      {
+	unique_lock<_Mutex> __lk(_M_mut, __rel_time);
+	if (__lk.owns_lock())
+	  {
+	    unsigned __num_readers = _M_state & _M_n_readers;
+	    if (!(_M_state & _S_write_entered)
+		&& __num_readers != _M_n_readers)
+	      {
+		++__num_readers;
+		_M_state &= ~_M_n_readers;
+		_M_state |= __num_readers;
+		return true;
+	      }
+	  }
+	return false;
+      }
+
+    template <typename _Clock, typename _Duration>
+      bool
+      try_lock_shared_until(const chrono::time_point<_Clock,
+						     _Duration>& __abs_time)
+      {
+	unique_lock<_Mutex> __lk(_M_mut, __abs_time);
+	if (__lk.owns_lock())
+	  {
+	    unsigned __num_readers = _M_state & _M_n_readers;
+	    if (!(_M_state & _S_write_entered)
+		&& __num_readers != _M_n_readers)
+	      {
+		++__num_readers;
+		_M_state &= ~_M_n_readers;
+		_M_state |= __num_readers;
+		return true;
+	      }
+	  }
+	return false;
+      }
+#endif
+
+    void
+    unlock_shared()
+    {
+      lock_guard<_Mutex> __lk(_M_mut);
+      unsigned __num_readers = (_M_state & _M_n_readers) - 1;
+      _M_state &= ~_M_n_readers;
+      _M_state |= __num_readers;
+      if (_M_state & _S_write_entered)
+	{
+	  if (__num_readers == 0)
+	    _M_gate2.notify_one();
+	}
+      else
+	{
+	  if (__num_readers == _M_n_readers - 1)
+	    _M_gate1.notify_one();
+	}
+    }
+  };
+#endif // _GLIBCXX_HAS_GTHREADS && _GLIBCXX_USE_C99_STDINT_TR1
+
+  /// shared_lock
+  template<typename _Mutex>
+    class shared_lock
+    {
+    public:
+      typedef _Mutex mutex_type;
+
+      // Shared locking
+
+      shared_lock() noexcept : _M_pm(nullptr), _M_owns(false) { }
+
+      explicit
+      shared_lock(mutex_type& __m) : _M_pm(&__m), _M_owns(true)
+      { __m.lock_shared(); }
+
+      shared_lock(mutex_type& __m, defer_lock_t) noexcept
+      : _M_pm(&__m), _M_owns(false) { }
+
+      shared_lock(mutex_type& __m, try_to_lock_t)
+      : _M_pm(&__m), _M_owns(__m.try_lock_shared()) { }
+
+      shared_lock(mutex_type& __m, adopt_lock_t)
+      : _M_pm(&__m), _M_owns(true) { }
+
+      template<typename _Clock, typename _Duration>
+	shared_lock(mutex_type& __m,
+		    const chrono::time_point<_Clock, _Duration>& __abs_time)
+      : _M_pm(&__m), _M_owns(__m.try_lock_shared_until(__abs_time)) { }
+
+      template<typename _Rep, typename _Period>
+	shared_lock(mutex_type& __m,
+		    const chrono::duration<_Rep, _Period>& __rel_time)
+      : _M_pm(&__m), _M_owns(__m.try_lock_shared_for(__rel_time)) { }
+
+      ~shared_lock()
+      {
+	if (_M_owns)
+	  _M_pm->unlock_shared();
+      }
+
+      shared_lock(shared_lock const&) = delete;
+      shared_lock& operator=(shared_lock const&) = delete;
+
+      shared_lock(shared_lock&& __sl) noexcept : shared_lock()
+      { swap(__sl); }
+
+      shared_lock&
+      operator=(shared_lock&& __sl) noexcept
+      { shared_lock(std::move(__sl)).swap(*this); }
+
+      void
+      lock()
+      {
+	_M_lockable();
+	_M_pm->lock_shared();
+	_M_owns = true;
+      }
+
+      bool
+      try_lock()
+      {
+	_M_lockable();
+	return _M_owns = _M_pm->try_lock_shared();
+      }
+
+      template<typename _Rep, typename _Period>
+	bool
+	try_lock_for(const chrono::duration<_Rep, _Period>& __rel_time)
+	{
+	  _M_lockable();
+	  return _M_owns = _M_pm->try_lock_shared_for(__rel_time);
+	}
+
+      template<typename _Clock, typename _Duration>
+	bool
+	try_lock_until(const chrono::time_point<_Clock, _Duration>& __abs_time)
+	{
+	  _M_lockable();
+	  return _M_owns = _M_pm->try_lock_shared_until(__abs_time);
+	}
+
+      void
+      unlock()
+      {
+	if (!_M_owns)
+	  __throw_system_error(int(errc::resource_deadlock_would_occur));
+	_M_pm->unlock_shared();
+	_M_owns = false;
+      }
+
+      // Setters
+
+      void
+      swap(shared_lock& __u) noexcept
+      {
+	std::swap(_M_pm, __u._M_pm);
+	std::swap(_M_owns, __u._M_owns);
+      }
+
+      mutex_type*
+      release() noexcept
+      {
+	_M_owns = false;
+	return std::exchange(_M_pm, nullptr);
+      }
+
+      // Getters
+
+      bool owns_lock() const noexcept { return _M_owns; }
+
+      explicit operator bool() const noexcept { return _M_owns; }
+
+      mutex_type* mutex() const noexcept { return _M_pm; }
+
+    private:
+      void
+      _M_lockable() const
+      {
+	if (_M_pm == nullptr)
+	  __throw_system_error(int(errc::operation_not_permitted));
+	if (_M_owns)
+	  __throw_system_error(int(errc::resource_deadlock_would_occur));
+      }
+
+      mutex_type*	_M_pm;
+      bool		_M_owns;
+    };
+
+  /// Swap specialization for shared_lock
+  template<typename _Mutex>
+    void
+    swap(shared_lock<_Mutex>& __x, shared_lock<_Mutex>& __y) noexcept
+    { __x.swap(__y); }
+
+  // @} group mutexes
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
+
+#endif // C++14
+
+#endif // _GLIBCXX_SHARED_MUTEX
diff --git a/libstdc++-v3/testsuite/30_threads/shared_lock/cons/1.cc b/libstdc++-v3/testsuite/30_threads/shared_lock/cons/1.cc
new file mode 100644
index 0000000..c05044e
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/shared_lock/cons/1.cc
@@ -0,0 +1,53 @@ 
+// { dg-do run { target *-*-freebsd* *-*-netbsd* *-*-linux* *-*-solaris* *-*-cygwin *-*-darwin* powerpc-ibm-aix* } }
+// { dg-options " -std=gnu++1y -pthread" { target *-*-freebsd* *-*-netbsd* *-*-linux* powerpc-ibm-aix* } }
+// { dg-options " -std=gnu++1y -pthreads" { target *-*-solaris* } }
+// { dg-options " -std=gnu++1y " { target *-*-cygwin *-*-darwin* } }
+// { dg-require-cstdint "" }
+// { dg-require-gthreads "" }
+
+// Copyright (C) 2013 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.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+
+#include <shared_mutex>
+#include <system_error>
+#include <testsuite_hooks.h>
+
+int main()
+{
+  bool test __attribute__((unused)) = true;
+  typedef std::shared_mutex mutex_type;
+  typedef std::shared_lock<mutex_type> lock_type;
+
+  try
+    {
+      lock_type lock;
+
+      VERIFY( !lock.owns_lock() );
+      VERIFY( !(bool)lock );
+    }
+  catch (const std::system_error& e)
+    {
+      VERIFY( false );
+    }
+  catch (...)
+    {
+      VERIFY( false );
+    }
+
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/30_threads/shared_lock/cons/2.cc b/libstdc++-v3/testsuite/30_threads/shared_lock/cons/2.cc
new file mode 100644
index 0000000..02d1d6b
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/shared_lock/cons/2.cc
@@ -0,0 +1,54 @@ 
+// { dg-do run { target *-*-freebsd* *-*-netbsd* *-*-linux* *-*-solaris* *-*-cygwin *-*-darwin* powerpc-ibm-aix* } }
+// { dg-options " -std=gnu++1y -pthread" { target *-*-freebsd* *-*-netbsd* *-*-linux* powerpc-ibm-aix* } }
+// { dg-options " -std=gnu++1y -pthreads" { target *-*-solaris* } }
+// { dg-options " -std=gnu++1y " { target *-*-cygwin *-*-darwin* } }
+// { dg-require-cstdint "" }
+// { dg-require-gthreads "" }
+
+// Copyright (C) 2013 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.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+
+#include <shared_mutex>
+#include <system_error>
+#include <testsuite_hooks.h>
+
+int main()
+{
+  bool test __attribute__((unused)) = true;
+  typedef std::shared_mutex mutex_type;
+  typedef std::shared_lock<mutex_type> lock_type;
+
+  try
+    {
+      mutex_type m;
+      lock_type lock(m);
+
+      VERIFY( lock.owns_lock() );
+      VERIFY( (bool)lock );
+    }
+  catch (const std::system_error& e)
+    {
+      VERIFY( false );
+    }
+  catch (...)
+    {
+      VERIFY( false );
+    }
+
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/30_threads/shared_lock/cons/3.cc b/libstdc++-v3/testsuite/30_threads/shared_lock/cons/3.cc
new file mode 100644
index 0000000..9af2bfa
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/shared_lock/cons/3.cc
@@ -0,0 +1,54 @@ 
+// { dg-do run { target *-*-freebsd* *-*-netbsd* *-*-linux* *-*-solaris* *-*-cygwin *-*-darwin* powerpc-ibm-aix* } }
+// { dg-options " -std=gnu++1y -pthread" { target *-*-freebsd* *-*-netbsd* *-*-linux* powerpc-ibm-aix* } }
+// { dg-options " -std=gnu++1y -pthreads" { target *-*-solaris* } }
+// { dg-options " -std=gnu++1y " { target *-*-cygwin *-*-darwin* } }
+// { dg-require-cstdint "" }
+// { dg-require-gthreads "" }
+
+// Copyright (C) 2013 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.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+
+#include <shared_mutex>
+#include <system_error>
+#include <testsuite_hooks.h>
+
+int main()
+{
+  bool test __attribute__((unused)) = true;
+  typedef std::shared_mutex mutex_type;
+  typedef std::shared_lock<mutex_type> lock_type;
+
+  try
+    {
+      mutex_type m;
+      lock_type lock(m, std::defer_lock);
+
+      VERIFY( !lock.owns_lock() );
+      VERIFY( !(bool)lock );
+    }
+  catch (const std::system_error& e)
+    {
+      VERIFY( false );
+    }
+  catch (...)
+    {
+      VERIFY( false );
+    }
+
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/30_threads/shared_lock/cons/4.cc b/libstdc++-v3/testsuite/30_threads/shared_lock/cons/4.cc
new file mode 100644
index 0000000..e80d1ae
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/shared_lock/cons/4.cc
@@ -0,0 +1,54 @@ 
+// { dg-do run { target *-*-freebsd* *-*-netbsd* *-*-linux* *-*-solaris* *-*-cygwin *-*-darwin* powerpc-ibm-aix* } }
+// { dg-options " -std=gnu++1y -pthread" { target *-*-freebsd* *-*-netbsd* *-*-linux* powerpc-ibm-aix* } }
+// { dg-options " -std=gnu++1y -pthreads" { target *-*-solaris* } }
+// { dg-options " -std=gnu++1y " { target *-*-cygwin *-*-darwin* } }
+// { dg-require-cstdint "" }
+// { dg-require-gthreads "" }
+
+// Copyright (C) 2013 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.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+
+#include <shared_mutex>
+#include <system_error>
+#include <testsuite_hooks.h>
+
+int main()
+{
+  bool test __attribute__((unused)) = true;
+  typedef std::shared_mutex mutex_type;
+  typedef std::shared_lock<mutex_type> lock_type;
+
+  try
+    {
+      mutex_type m;
+      lock_type lock(m, std::try_to_lock);
+
+      VERIFY( lock.owns_lock() );
+      VERIFY( (bool)lock );
+    }
+  catch (const std::system_error& e)
+    {
+      VERIFY( false );
+    }
+  catch (...)
+    {
+      VERIFY( false );
+    }
+
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/30_threads/shared_lock/cons/5.cc b/libstdc++-v3/testsuite/30_threads/shared_lock/cons/5.cc
new file mode 100644
index 0000000..95a704c
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/shared_lock/cons/5.cc
@@ -0,0 +1,58 @@ 
+// { dg-do run { target *-*-freebsd* *-*-netbsd* *-*-linux* *-*-solaris* *-*-cygwin *-*-darwin* powerpc-ibm-aix* } }
+// { dg-options " -std=gnu++1y -pthread" { target *-*-freebsd* *-*-netbsd* *-*-linux* powerpc-ibm-aix* } }
+// { dg-options " -std=gnu++1y -pthreads" { target *-*-solaris* } }
+// { dg-options " -std=gnu++1y " { target *-*-cygwin *-*-darwin* } }
+// { dg-require-cstdint "" }
+// { dg-require-gthreads-timed "" }
+
+// Copyright (C) 2013 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.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+
+#include <chrono>
+#include <shared_mutex>
+#include <system_error>
+#include <testsuite_hooks.h>
+
+int main()
+{
+  bool test __attribute__((unused)) = true;
+  typedef std::shared_mutex mutex_type;
+  typedef std::shared_lock<mutex_type> lock_type;
+  typedef std::chrono::system_clock clock_type;
+
+  try
+    {
+      clock_type::time_point t = clock_type::now() + std::chrono::seconds(5);
+
+      mutex_type m;
+      lock_type lock(m, t);
+
+      VERIFY( lock.owns_lock() );
+      VERIFY( (bool)lock );
+    }
+  catch (const std::system_error& e)
+    {
+      VERIFY( false );
+    }
+  catch (...)
+    {
+      VERIFY( false );
+    }
+
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/30_threads/shared_lock/cons/6.cc b/libstdc++-v3/testsuite/30_threads/shared_lock/cons/6.cc
new file mode 100644
index 0000000..a1a8eea
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/shared_lock/cons/6.cc
@@ -0,0 +1,58 @@ 
+// { dg-do run { target *-*-freebsd* *-*-netbsd* *-*-linux* *-*-solaris* *-*-cygwin *-*-darwin* powerpc-ibm-aix* } }
+// { dg-options " -std=gnu++1y -pthread" { target *-*-freebsd* *-*-netbsd* *-*-linux* powerpc-ibm-aix* } }
+// { dg-options " -std=gnu++1y -pthreads" { target *-*-solaris* } }
+// { dg-options " -std=gnu++1y " { target *-*-cygwin *-*-darwin* } }
+// { dg-require-cstdint "" }
+// { dg-require-gthreads-timed "" }
+
+// Copyright (C) 2013 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.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+
+#include <chrono>
+#include <shared_mutex>
+#include <system_error>
+#include <testsuite_hooks.h>
+
+int main()
+{
+  bool test __attribute__((unused)) = true;
+  typedef std::shared_mutex mutex_type;
+  typedef std::shared_lock<mutex_type> lock_type;
+  typedef std::chrono::system_clock clock_type;
+
+  try
+    {
+      clock_type::duration d = std::chrono::seconds(5);
+
+      mutex_type m;
+      lock_type lock(m, d);
+
+      VERIFY( lock.owns_lock() );
+      VERIFY( (bool)lock );
+    }
+  catch (const std::system_error& e)
+    {
+      VERIFY( false );
+    }
+  catch (...)
+    {
+      VERIFY( false );
+    }
+
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/30_threads/shared_lock/locking/1.cc b/libstdc++-v3/testsuite/30_threads/shared_lock/locking/1.cc
new file mode 100644
index 0000000..1d52cd9
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/shared_lock/locking/1.cc
@@ -0,0 +1,61 @@ 
+// { dg-do run { target *-*-freebsd* *-*-netbsd* *-*-linux* *-*-solaris* *-*-cygwin *-*-darwin* powerpc-ibm-aix* } }
+// { dg-options " -std=gnu++1y -pthread" { target *-*-freebsd* *-*-netbsd* *-*-linux* powerpc-ibm-aix* } }
+// { dg-options " -std=gnu++1y -pthreads" { target *-*-solaris* } }
+// { dg-options " -std=gnu++1y " { target *-*-cygwin *-*-darwin* } }
+// { dg-require-cstdint "" }
+// { dg-require-gthreads "" }
+
+// Copyright (C) 2013 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.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+
+#include <shared_mutex>
+#include <system_error>
+#include <testsuite_hooks.h>
+
+int main()
+{
+  bool test __attribute__((unused)) = true;
+  typedef std::shared_mutex mutex_type;
+  typedef std::shared_lock<mutex_type> lock_type;
+
+  try
+    {
+      mutex_type m;
+      lock_type l(m, std::defer_lock);
+
+      l.lock();
+
+      VERIFY( (bool)l );
+      VERIFY( l.owns_lock() );
+
+      l.unlock();
+
+      VERIFY( !(bool)l );
+      VERIFY( !l.owns_lock() );
+    }
+  catch (const std::system_error& e)
+    {
+      VERIFY( false );
+    }
+  catch (...)
+    {
+      VERIFY( false );
+    }
+
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/30_threads/shared_lock/locking/2.cc b/libstdc++-v3/testsuite/30_threads/shared_lock/locking/2.cc
new file mode 100644
index 0000000..38886d9
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/shared_lock/locking/2.cc
@@ -0,0 +1,106 @@ 
+// { dg-do run { target *-*-freebsd* *-*-netbsd* *-*-linux* *-*-solaris* *-*-cygwin *-*-darwin* powerpc-ibm-aix* } }
+// { dg-options " -std=gnu++1y -pthread" { target *-*-freebsd* *-*-netbsd* *-*-linux* powerpc-ibm-aix* } }
+// { dg-options " -std=gnu++1y -pthreads" { target *-*-solaris* } }
+// { dg-options " -std=gnu++1y " { target *-*-cygwin *-*-darwin* } }
+// { dg-require-cstdint "" }
+// { dg-require-gthreads "" }
+
+// Copyright (C) 2013 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.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+
+#include <shared_mutex>
+#include <system_error>
+#include <testsuite_hooks.h>
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  typedef std::shared_mutex mutex_type;
+  typedef std::shared_lock<mutex_type> lock_type;
+
+  try
+    {
+      lock_type l;
+
+      // Lock shared_lock w/o mutex
+      try
+        {
+          l.lock();
+        }
+      catch (const std::system_error& ex)
+        {
+	  VERIFY( ex.code() == std::make_error_code
+		  (std::errc::operation_not_permitted) );
+        }
+      catch (...)
+        {
+          VERIFY( false );
+        }
+    }
+  catch (const std::system_error& e)
+    {
+      VERIFY( false );
+    }
+  catch (...)
+    {
+      VERIFY( false );
+    }
+}
+
+
+void test02()
+{
+  bool test __attribute__((unused)) = true;
+  typedef std::shared_mutex mutex_type;
+  typedef std::shared_lock<mutex_type> lock_type;
+
+  try
+    {
+      mutex_type m;
+      lock_type l(m);
+
+      // Lock already locked shared_lock.
+      try
+	{
+	  l.lock();
+	}
+      catch (const std::system_error& ex)
+	{
+	  VERIFY( ex.code() == std::make_error_code
+		  (std::errc::resource_deadlock_would_occur) );
+	}
+      catch (...)
+	{
+	  VERIFY( false );
+	}
+    }
+  catch (const std::system_error& e)
+    {
+      VERIFY( false );
+    }
+  catch (...)
+    {
+      VERIFY( false );
+    }
+}
+
+int main()
+{
+  test01();
+  test02();
+}
diff --git a/libstdc++-v3/testsuite/30_threads/shared_lock/locking/3.cc b/libstdc++-v3/testsuite/30_threads/shared_lock/locking/3.cc
new file mode 100644
index 0000000..a8b3ff7
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/shared_lock/locking/3.cc
@@ -0,0 +1,67 @@ 
+// { dg-do run { target *-*-freebsd* *-*-netbsd* *-*-linux* *-*-solaris* *-*-cygwin *-*-darwin* powerpc-ibm-aix* } }
+// { dg-options " -std=gnu++1y -pthread" { target *-*-freebsd* *-*-netbsd* *-*-linux* powerpc-ibm-aix* } }
+// { dg-options " -std=gnu++1y -pthreads" { target *-*-solaris* } }
+// { dg-options " -std=gnu++1y " { target *-*-cygwin *-*-darwin* } }
+// { dg-require-cstdint "" }
+// { dg-require-gthreads-timed "" }
+
+// Copyright (C) 2013 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.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+
+#include <chrono>
+#include <shared_mutex>
+#include <system_error>
+#include <testsuite_hooks.h>
+
+int main()
+{
+  bool test __attribute__((unused)) = true;
+  typedef std::shared_mutex mutex_type;
+  typedef std::shared_lock<mutex_type> lock_type;
+
+  try
+    {
+      mutex_type m;
+      lock_type l(m, std::defer_lock);
+
+      try
+	{
+	  l.try_lock_for(std::chrono::milliseconds(100));
+	}
+      catch(const std::system_error&)
+	{
+	  VERIFY( false );
+	}
+      catch (...)
+	{
+	  VERIFY( false );
+	}
+
+      VERIFY( l.owns_lock() );
+    }
+  catch (const std::system_error&)
+    {
+      VERIFY( false );
+    }
+  catch (...)
+    {
+      VERIFY( false );
+    }
+
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/30_threads/shared_lock/locking/4.cc b/libstdc++-v3/testsuite/30_threads/shared_lock/locking/4.cc
new file mode 100644
index 0000000..4b4743e
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/shared_lock/locking/4.cc
@@ -0,0 +1,69 @@ 
+// { dg-do run { target *-*-freebsd* *-*-netbsd* *-*-linux* *-*-solaris* *-*-cygwin *-*-darwin* powerpc-ibm-aix* } }
+// { dg-options " -std=gnu++1y -pthread" { target *-*-freebsd* *-*-netbsd* *-*-linux* powerpc-ibm-aix* } }
+// { dg-options " -std=gnu++1y -pthreads" { target *-*-solaris* } }
+// { dg-options " -std=gnu++1y " { target *-*-cygwin *-*-darwin* } }
+// { dg-require-cstdint "" }
+// { dg-require-gthreads-timed "" }
+
+// Copyright (C) 2013 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.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+
+#include <chrono>
+#include <shared_mutex>
+#include <system_error>
+#include <testsuite_hooks.h>
+
+int main()
+{
+  bool test __attribute__((unused)) = true;
+  typedef std::shared_mutex mutex_type;
+  typedef std::shared_lock<mutex_type> lock_type;
+  typedef std::chrono::system_clock clock_type;
+
+  try
+    {
+      mutex_type m;
+      lock_type l(m, std::defer_lock);
+      clock_type::time_point t = clock_type::now() + std::chrono::seconds(1);
+
+      try
+	{
+	  l.try_lock_until(t);
+	}
+      catch(const std::system_error&)
+	{
+	  VERIFY( false );
+	}
+      catch (...)
+	{
+	  VERIFY( false );
+	}
+
+      VERIFY( l.owns_lock() );
+    }
+  catch (const std::system_error& e)
+    {
+      VERIFY( false );
+    }
+  catch (...)
+    {
+      VERIFY( false );
+    }
+
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/30_threads/shared_lock/modifiers/1.cc b/libstdc++-v3/testsuite/30_threads/shared_lock/modifiers/1.cc
new file mode 100644
index 0000000..fd661de
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/shared_lock/modifiers/1.cc
@@ -0,0 +1,68 @@ 
+// { dg-do run { target *-*-freebsd* *-*-netbsd* *-*-linux* *-*-solaris* *-*-cygwin *-*-darwin* powerpc-ibm-aix* } }
+// { dg-options " -std=gnu++1y -pthread" { target *-*-freebsd* *-*-netbsd* *-*-linux* powerpc-ibm-aix* } }
+// { dg-options " -std=gnu++1y -pthreads" { target *-*-solaris* } }
+// { dg-options " -std=gnu++1y " { target *-*-cygwin *-*-darwin* } }
+// { dg-require-cstdint "" }
+// { dg-require-gthreads "" }
+
+// Copyright (C) 2013 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.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+
+#include <shared_mutex>
+#include <system_error>
+#include <testsuite_hooks.h>
+
+int main()
+{
+  bool test __attribute__((unused)) = true;
+  typedef std::shared_mutex mutex_type;
+  typedef std::shared_lock<mutex_type> lock_type;
+
+  try
+    {
+      mutex_type m;
+      lock_type l1(m);
+      lock_type l2;
+
+      try
+	{
+	  l1.swap(l2);
+	}
+      catch (const std::system_error&)
+	{
+	  VERIFY( false );
+	}
+      catch(...)
+	{
+	  VERIFY( false );
+	}
+
+      VERIFY( !(bool)l1 );
+      VERIFY( (bool)l2 );
+    }
+  catch (const std::system_error& e)
+    {
+      VERIFY( false );
+    }
+  catch (...)
+    {
+      VERIFY( false );
+    }
+
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/30_threads/shared_lock/modifiers/2.cc b/libstdc++-v3/testsuite/30_threads/shared_lock/modifiers/2.cc
new file mode 100644
index 0000000..c223400
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/shared_lock/modifiers/2.cc
@@ -0,0 +1,68 @@ 
+// { dg-do run { target *-*-freebsd* *-*-netbsd* *-*-linux* *-*-solaris* *-*-cygwin *-*-darwin* powerpc-ibm-aix* } }
+// { dg-options " -std=gnu++1y -pthread" { target *-*-freebsd* *-*-netbsd* *-*-linux* powerpc-ibm-aix* } }
+// { dg-options " -std=gnu++1y -pthreads" { target *-*-solaris* } }
+// { dg-options " -std=gnu++1y " { target *-*-cygwin *-*-darwin* } }
+// { dg-require-cstdint "" }
+// { dg-require-gthreads "" }
+
+// Copyright (C) 2013 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.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+
+#include <shared_mutex>
+#include <system_error>
+#include <testsuite_hooks.h>
+
+int main()
+{
+  bool test __attribute__((unused)) = true;
+  typedef std::shared_mutex mutex_type;
+  typedef std::shared_lock<mutex_type> lock_type;
+
+  try
+    {
+      mutex_type m;
+      lock_type l1(m);
+      lock_type l2;
+
+      try
+	{
+	  l1.swap(l2);
+	}
+      catch (const std::system_error&)
+	{
+	  VERIFY( false );
+	}
+      catch(...)
+	{
+	  VERIFY( false );
+	}
+
+      VERIFY( !(bool)l1 );
+      VERIFY( (bool)l2 );
+    }
+  catch (const std::system_error&)
+    {
+      VERIFY( false );
+    }
+  catch (...)
+    {
+      VERIFY( false );
+    }
+
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/30_threads/shared_lock/requirements/explicit_instantiation.cc b/libstdc++-v3/testsuite/30_threads/shared_lock/requirements/explicit_instantiation.cc
new file mode 100644
index 0000000..53d7a98
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/shared_lock/requirements/explicit_instantiation.cc
@@ -0,0 +1,31 @@ 
+// { dg-do compile }
+// { dg-options "-std=gnu++1y" }
+// { dg-require-cstdint "" }
+// { dg-require-gthreads "" }
+
+// Copyright (C) 2013 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.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+
+// NB: This file is for testing with NO OTHER INCLUDES.
+
+#include <shared_mutex>
+
+namespace std
+{
+  template class shared_lock<shared_mutex>;
+}
diff --git a/libstdc++-v3/testsuite/30_threads/shared_lock/requirements/typedefs.cc b/libstdc++-v3/testsuite/30_threads/shared_lock/requirements/typedefs.cc
new file mode 100644
index 0000000..cd4fa3e
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/shared_lock/requirements/typedefs.cc
@@ -0,0 +1,33 @@ 
+// { dg-do compile }
+// { dg-options "-std=gnu++1y" }
+// { dg-require-cstdint "" }
+// { dg-require-gthreads "" }
+
+// Copyright (C) 2013 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.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+
+// NB: This file is for testing with NO OTHER INCLUDES.
+
+#include <shared_mutex>
+
+void test01()
+{
+  // Check for required typedefs
+  typedef std::shared_lock<std::shared_mutex> test_type;
+  typedef test_type::mutex_type mutex_type;
+}
diff --git a/libstdc++-v3/testsuite/30_threads/shared_mutex/cons/1.cc b/libstdc++-v3/testsuite/30_threads/shared_mutex/cons/1.cc
new file mode 100644
index 0000000..794e8ae
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/shared_mutex/cons/1.cc
@@ -0,0 +1,49 @@ 
+// { dg-do run { target *-*-freebsd* *-*-netbsd* *-*-linux* *-*-solaris* *-*-cygwin *-*-darwin* powerpc-ibm-aix* } }
+// { dg-options " -std=gnu++1y -pthread" { target *-*-freebsd* *-*-netbsd* *-*-linux* powerpc-ibm-aix* } }
+// { dg-options " -std=gnu++1y -pthreads" { target *-*-solaris* } }
+// { dg-options " -std=gnu++1y " { target *-*-cygwin *-*-darwin* } }
+// { dg-require-cstdint "" }
+// { dg-require-gthreads "" }
+
+// Copyright (C) 2013 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.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+
+#include <shared_mutex>
+#include <system_error>
+#include <testsuite_hooks.h>
+
+int main()
+{
+  bool test __attribute__((unused)) = true;
+  typedef std::shared_mutex mutex_type;
+
+  try
+    {
+      mutex_type m1;
+    }
+  catch (const std::system_error& e)
+    {
+      VERIFY( false );
+    }
+  catch (...)
+    {
+      VERIFY( false );
+    }
+
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/30_threads/shared_mutex/cons/assign_neg.cc b/libstdc++-v3/testsuite/30_threads/shared_mutex/cons/assign_neg.cc
new file mode 100644
index 0000000..092cd10
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/shared_mutex/cons/assign_neg.cc
@@ -0,0 +1,35 @@ 
+// { dg-do compile }
+// { dg-options "-std=gnu++1y" }
+// { dg-require-cstdint "" }
+// { dg-require-gthreads "" }
+
+// Copyright (C) 2008-2013 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.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+
+#include <shared_mutex>
+
+void test01()
+{
+  // assign
+  typedef std::shared_mutex mutex_type;
+  mutex_type m1;
+  mutex_type m2;
+  m1 = m2;			// { dg-error "deleted" }
+}
+
+// { dg-prune-output "include" }
diff --git a/libstdc++-v3/testsuite/30_threads/shared_mutex/cons/copy_neg.cc b/libstdc++-v3/testsuite/30_threads/shared_mutex/cons/copy_neg.cc
new file mode 100644
index 0000000..a9faf27
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/shared_mutex/cons/copy_neg.cc
@@ -0,0 +1,34 @@ 
+// { dg-do compile }
+// { dg-options "-std=gnu++1y" }
+// { dg-require-cstdint "" }
+// { dg-require-gthreads "" }
+
+// Copyright (C) 2013 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.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+
+#include <shared_mutex>
+
+void test01()
+{
+  // assign
+  typedef std::shared_mutex mutex_type;
+  mutex_type m1;
+  mutex_type m2(m1);		// { dg-error "deleted" }
+}
+
+// { dg-prune-output "include" }
diff --git a/libstdc++-v3/testsuite/30_threads/shared_mutex/requirements/standard_layout.cc b/libstdc++-v3/testsuite/30_threads/shared_mutex/requirements/standard_layout.cc
new file mode 100644
index 0000000..84f22cc
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/shared_mutex/requirements/standard_layout.cc
@@ -0,0 +1,31 @@ 
+// { dg-do compile }
+// { dg-options "-std=gnu++1y" }
+// { dg-require-cstdint "" }
+// { dg-require-gthreads "" }
+
+// Copyright (C) 2013 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.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+
+#include <shared_mutex>
+#include <testsuite_common_types.h>
+
+void test01()
+{
+  __gnu_test::standard_layout test;
+  test.operator()<std::shared_mutex>();
+}
diff --git a/libstdc++-v3/testsuite/30_threads/shared_mutex/try_lock/1.cc b/libstdc++-v3/testsuite/30_threads/shared_mutex/try_lock/1.cc
new file mode 100644
index 0000000..7381ec2
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/shared_mutex/try_lock/1.cc
@@ -0,0 +1,52 @@ 
+// { dg-do run { target *-*-freebsd* *-*-netbsd* *-*-linux* *-*-solaris* *-*-cygwin *-*-darwin* powerpc-ibm-aix* } }
+// { dg-options " -std=gnu++1y -pthread" { target *-*-freebsd* *-*-netbsd* *-*-linux* powerpc-ibm-aix* } }
+// { dg-options " -std=gnu++1y -pthreads" { target *-*-solaris* } }
+// { dg-options " -std=gnu++1y " { target *-*-cygwin *-*-darwin* } }
+// { dg-require-cstdint "" }
+// { dg-require-gthreads "" }
+
+// Copyright (C) 2013 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.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+
+#include <shared_mutex>
+#include <system_error>
+#include <testsuite_hooks.h>
+
+int main()
+{
+  bool test __attribute__((unused)) = true;
+  typedef std::shared_mutex mutex_type;
+
+  try
+    {
+      mutex_type m;
+      bool b = m.try_lock();
+      VERIFY( b );
+      m.unlock();
+    }
+  catch (const std::system_error& e)
+    {
+      VERIFY( false );
+    }
+  catch (...)
+    {
+      VERIFY( false );
+    }
+
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/30_threads/shared_mutex/try_lock/2.cc b/libstdc++-v3/testsuite/30_threads/shared_mutex/try_lock/2.cc
new file mode 100644
index 0000000..393d9f2
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/shared_mutex/try_lock/2.cc
@@ -0,0 +1,67 @@ 
+// { dg-do run { target *-*-freebsd* *-*-netbsd* *-*-linux* *-*-solaris* *-*-cygwin *-*-darwin* powerpc-ibm-aix* } }
+// { dg-options " -std=gnu++1y -pthread" { target *-*-freebsd* *-*-netbsd* *-*-linux* powerpc-ibm-aix* } }
+// { dg-options " -std=gnu++1y -pthreads" { target *-*-solaris* } }
+// { dg-options " -std=gnu++1y " { target *-*-cygwin *-*-darwin* } }
+// { dg-require-cstdint "" }
+// { dg-require-gthreads "" }
+
+// Copyright (C) 2013 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.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+
+#include <shared_mutex>
+#include <thread>
+#include <system_error>
+#include <testsuite_hooks.h>
+
+int main()
+{
+  bool test __attribute__((unused)) = true;
+  typedef std::shared_mutex mutex_type;
+
+  try
+    {
+      mutex_type m;
+      m.lock();
+      bool b;
+
+      std::thread t([&] {
+        try
+          {
+            b = m.try_lock();
+          }
+        catch (const std::system_error& e)
+          {
+            VERIFY( false );
+          }
+      });
+      t.join();
+      VERIFY( !b );
+
+      m.unlock();
+    }
+  catch (const std::system_error& e)
+    {
+      VERIFY( false );
+    }
+  catch (...)
+    {
+      VERIFY( false );
+    }
+
+  return 0;
+}