[libcxx] r241067 - Implement N4508: shared_mutex. Reviewed as http://reviews.llvm.org/D10480

Marshall Clow mclow.lists at gmail.com
Tue Jun 30 07:04:14 PDT 2015


Author: marshall
Date: Tue Jun 30 09:04:14 2015
New Revision: 241067

URL: http://llvm.org/viewvc/llvm-project?rev=241067&view=rev
Log:
Implement N4508: shared_mutex. Reviewed as http://reviews.llvm.org/D10480

Added:
    libcxx/trunk/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/
    libcxx/trunk/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/nothing_to_do.pass.cpp
    libcxx/trunk/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/
    libcxx/trunk/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/assign.fail.cpp
    libcxx/trunk/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/copy.fail.cpp
    libcxx/trunk/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/default.pass.cpp
    libcxx/trunk/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/lock.pass.cpp
    libcxx/trunk/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/lock_shared.pass.cpp
    libcxx/trunk/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/try_lock.pass.cpp
    libcxx/trunk/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/try_lock_shared.pass.cpp
Modified:
    libcxx/trunk/include/shared_mutex
    libcxx/trunk/src/shared_mutex.cpp

Modified: libcxx/trunk/include/shared_mutex
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/shared_mutex?rev=241067&r1=241066&r2=241067&view=diff
==============================================================================
--- libcxx/trunk/include/shared_mutex (original)
+++ libcxx/trunk/include/shared_mutex Tue Jun 30 09:04:14 2015
@@ -19,6 +19,29 @@
 namespace std
 {
 
+class shared_mutex      // C++17
+{
+public:
+    shared_mutex();
+    ~shared_mutex();
+
+    shared_mutex(const shared_mutex&) = delete;
+    shared_mutex& operator=(const shared_mutex&) = delete;
+
+    // Exclusive ownership
+    void lock(); // blocking
+    bool try_lock();
+    void unlock();
+
+    // Shared ownership
+    void lock_shared(); // blocking
+    bool try_lock_shared();
+    void unlock_shared();
+
+    typedef implementation-defined native_handle_type; // See 30.2.3
+    native_handle_type native_handle(); // See 30.2.3
+};
+
 class shared_timed_mutex
 {
 public:
@@ -118,7 +141,7 @@ template <class Mutex>
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-class _LIBCPP_TYPE_VIS shared_timed_mutex
+struct _LIBCPP_TYPE_VIS __shared_mutex_base
 {
     mutex               __mut_;
     condition_variable  __gate1_;
@@ -127,6 +150,58 @@ class _LIBCPP_TYPE_VIS shared_timed_mute
 
     static const unsigned __write_entered_ = 1U << (sizeof(unsigned)*__CHAR_BIT__ - 1);
     static const unsigned __n_readers_ = ~__write_entered_;
+
+    __shared_mutex_base();
+    _LIBCPP_INLINE_VISIBILITY ~__shared_mutex_base() = default;
+
+    __shared_mutex_base(const __shared_mutex_base&) = delete;
+    __shared_mutex_base& operator=(const __shared_mutex_base&) = delete;
+
+    // Exclusive ownership
+    void lock(); // blocking
+    bool try_lock();
+    void unlock();
+
+    // Shared ownership
+    void lock_shared(); // blocking
+    bool try_lock_shared();
+    void unlock_shared();
+
+//     typedef implementation-defined native_handle_type; // See 30.2.3
+//     native_handle_type native_handle(); // See 30.2.3
+};
+
+
+#if _LIBCPP_STD_VER > 14
+class _LIBCPP_TYPE_VIS shared_mutex
+{
+	__shared_mutex_base __base;
+public:
+    shared_mutex() : __base() {}
+    _LIBCPP_INLINE_VISIBILITY ~shared_mutex() = default;
+
+    shared_mutex(const shared_mutex&) = delete;
+    shared_mutex& operator=(const shared_mutex&) = delete;
+
+    // Exclusive ownership
+    _LIBCPP_INLINE_VISIBILITY void lock()     { return __base.lock(); }
+    _LIBCPP_INLINE_VISIBILITY bool try_lock() { return __base.try_lock(); }
+    _LIBCPP_INLINE_VISIBILITY void unlock()   { return __base.unlock(); }
+
+    // Shared ownership
+    _LIBCPP_INLINE_VISIBILITY void lock_shared()     { return __base.lock_shared(); }
+    _LIBCPP_INLINE_VISIBILITY bool try_lock_shared() { return __base.try_lock_shared(); }
+    _LIBCPP_INLINE_VISIBILITY void unlock_shared()   { return __base.unlock_shared(); }
+
+//     typedef __shared_mutex_base::native_handle_type native_handle_type;
+//     _LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() { return __base::unlock_shared(); }
+};
+#endif
+
+
+class _LIBCPP_TYPE_VIS shared_timed_mutex
+{
+	__shared_mutex_base __base;
 public:
     shared_timed_mutex();
     _LIBCPP_INLINE_VISIBILITY ~shared_timed_mutex() = default;
@@ -170,30 +245,30 @@ bool
 shared_timed_mutex::try_lock_until(
                         const chrono::time_point<_Clock, _Duration>& __abs_time)
 {
-    unique_lock<mutex> __lk(__mut_);
-    if (__state_ & __write_entered_)
+    unique_lock<mutex> __lk(__base.__mut_);
+    if (__base.__state_ & __base.__write_entered_)
     {
         while (true)
         {
-            cv_status __status = __gate1_.wait_until(__lk, __abs_time);
-            if ((__state_ & __write_entered_) == 0)
+            cv_status __status = __base.__gate1_.wait_until(__lk, __abs_time);
+            if ((__base.__state_ & __base.__write_entered_) == 0)
                 break;
             if (__status == cv_status::timeout)
                 return false;
         }
     }
-    __state_ |= __write_entered_;
-    if (__state_ & __n_readers_)
+    __base.__state_ |= __base.__write_entered_;
+    if (__base.__state_ & __base.__n_readers_)
     {
         while (true)
         {
-            cv_status __status = __gate2_.wait_until(__lk, __abs_time);
-            if ((__state_ & __n_readers_) == 0)
+            cv_status __status = __base.__gate2_.wait_until(__lk, __abs_time);
+            if ((__base.__state_ & __base.__n_readers_) == 0)
                 break;
             if (__status == cv_status::timeout)
             {
-                __state_ &= ~__write_entered_;
-                __gate1_.notify_all();
+                __base.__state_ &= ~__base.__write_entered_;
+                __base.__gate1_.notify_all();
                 return false;
             }
         }
@@ -206,22 +281,22 @@ bool
 shared_timed_mutex::try_lock_shared_until(
                         const chrono::time_point<_Clock, _Duration>& __abs_time)
 {
-    unique_lock<mutex> __lk(__mut_);
-    if ((__state_ & __write_entered_) || (__state_ & __n_readers_) == __n_readers_)
+    unique_lock<mutex> __lk(__base.__mut_);
+    if ((__base.__state_ & __base.__write_entered_) || (__base.__state_ & __base.__n_readers_) == __base.__n_readers_)
     {
         while (true)
         {
-            cv_status status = __gate1_.wait_until(__lk, __abs_time);
-            if ((__state_ & __write_entered_) == 0 &&
-                                       (__state_ & __n_readers_) < __n_readers_)
+            cv_status status = __base.__gate1_.wait_until(__lk, __abs_time);
+            if ((__base.__state_ & __base.__write_entered_) == 0 &&
+                                       (__base.__state_ & __base.__n_readers_) < __base.__n_readers_)
                 break;
             if (status == cv_status::timeout)
                 return false;
         }
     }
-    unsigned __num_readers = (__state_ & __n_readers_) + 1;
-    __state_ &= ~__n_readers_;
-    __state_ |= __num_readers;
+    unsigned __num_readers = (__base.__state_ & __base.__n_readers_) + 1;
+    __base.__state_ &= ~__base.__n_readers_;
+    __base.__state_ |= __num_readers;
     return true;
 }
 

Modified: libcxx/trunk/src/shared_mutex.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/src/shared_mutex.cpp?rev=241067&r1=241066&r2=241067&view=diff
==============================================================================
--- libcxx/trunk/src/shared_mutex.cpp (original)
+++ libcxx/trunk/src/shared_mutex.cpp Tue Jun 30 09:04:14 2015
@@ -15,7 +15,8 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-shared_timed_mutex::shared_timed_mutex()
+// Shared Mutex Base
+__shared_mutex_base::__shared_mutex_base()
     : __state_(0)
 {
 }
@@ -23,7 +24,7 @@ shared_timed_mutex::shared_timed_mutex()
 // Exclusive ownership
 
 void
-shared_timed_mutex::lock()
+__shared_mutex_base::lock()
 {
     unique_lock<mutex> lk(__mut_);
     while (__state_ & __write_entered_)
@@ -34,7 +35,7 @@ shared_timed_mutex::lock()
 }
 
 bool
-shared_timed_mutex::try_lock()
+__shared_mutex_base::try_lock()
 {
     unique_lock<mutex> lk(__mut_);
     if (__state_ == 0)
@@ -46,7 +47,7 @@ shared_timed_mutex::try_lock()
 }
 
 void
-shared_timed_mutex::unlock()
+__shared_mutex_base::unlock()
 {
     lock_guard<mutex> _(__mut_);
     __state_ = 0;
@@ -56,7 +57,7 @@ shared_timed_mutex::unlock()
 // Shared ownership
 
 void
-shared_timed_mutex::lock_shared()
+__shared_mutex_base::lock_shared()
 {
     unique_lock<mutex> lk(__mut_);
     while ((__state_ & __write_entered_) || (__state_ & __n_readers_) == __n_readers_)
@@ -67,7 +68,7 @@ shared_timed_mutex::lock_shared()
 }
 
 bool
-shared_timed_mutex::try_lock_shared()
+__shared_mutex_base::try_lock_shared()
 {
     unique_lock<mutex> lk(__mut_);
     unsigned num_readers = __state_ & __n_readers_;
@@ -82,7 +83,7 @@ shared_timed_mutex::try_lock_shared()
 }
 
 void
-shared_timed_mutex::unlock_shared()
+__shared_mutex_base::unlock_shared()
 {
     lock_guard<mutex> _(__mut_);
     unsigned num_readers = (__state_ & __n_readers_) - 1;
@@ -101,6 +102,16 @@ shared_timed_mutex::unlock_shared()
 }
 
 
+// Shared Timed Mutex
+// These routines are here for ABI stability
+shared_timed_mutex::shared_timed_mutex() : __base() {}
+void shared_timed_mutex::lock()     { return __base.lock(); }
+bool shared_timed_mutex::try_lock() { return __base.try_lock(); }
+void shared_timed_mutex::unlock()   { return __base.unlock(); }
+void shared_timed_mutex::lock_shared() { return __base.lock_shared(); }
+bool shared_timed_mutex::try_lock_shared() { return __base.try_lock_shared(); }
+void shared_timed_mutex::unlock_shared() { return __base.unlock_shared(); }
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif // !_LIBCPP_HAS_NO_THREADS

Added: libcxx/trunk/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/nothing_to_do.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/nothing_to_do.pass.cpp?rev=241067&view=auto
==============================================================================
--- libcxx/trunk/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/nothing_to_do.pass.cpp (added)
+++ libcxx/trunk/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/nothing_to_do.pass.cpp Tue Jun 30 09:04:14 2015
@@ -0,0 +1,12 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+int main()
+{
+}

Added: libcxx/trunk/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/assign.fail.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/assign.fail.cpp?rev=241067&view=auto
==============================================================================
--- libcxx/trunk/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/assign.fail.cpp (added)
+++ libcxx/trunk/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/assign.fail.cpp Tue Jun 30 09:04:14 2015
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <shared_mutex>
+
+// class shared_mutex;
+
+// shared_mutex& operator=(const shared_mutex&) = delete;
+
+#include <shared_mutex>
+
+#include "test_macros.h"
+
+int main()
+{
+#if TEST_STD_VER > 14
+    std::shared_mutex m0;
+    std::shared_mutex m1;
+    m1 = m0;
+#else
+#   error
+#endif
+}

Added: libcxx/trunk/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/copy.fail.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/copy.fail.cpp?rev=241067&view=auto
==============================================================================
--- libcxx/trunk/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/copy.fail.cpp (added)
+++ libcxx/trunk/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/copy.fail.cpp Tue Jun 30 09:04:14 2015
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <shared_mutex>
+
+// class shared_mutex;
+
+// shared_mutex(const shared_mutex&) = delete;
+
+#include <shared_mutex>
+
+#include "test_macros.h"
+
+int main()
+{
+#if TEST_STD_VER > 14
+    std::shared_mutex m0;
+    std::shared_mutex m1(m0);
+#else
+#   error
+#endif
+}

Added: libcxx/trunk/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/default.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/default.pass.cpp?rev=241067&view=auto
==============================================================================
--- libcxx/trunk/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/default.pass.cpp (added)
+++ libcxx/trunk/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/default.pass.cpp Tue Jun 30 09:04:14 2015
@@ -0,0 +1,24 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++03, c++98, c++11, c++14
+
+// <shared_mutex>
+
+// class shared_mutex;
+
+// shared_mutex();
+
+#include <shared_mutex>
+
+int main()
+{
+    std::shared_mutex m;
+}

Added: libcxx/trunk/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/lock.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/lock.pass.cpp?rev=241067&view=auto
==============================================================================
--- libcxx/trunk/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/lock.pass.cpp (added)
+++ libcxx/trunk/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/lock.pass.cpp Tue Jun 30 09:04:14 2015
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++03, c++98, c++11, c++14
+
+// <shared_mutex>
+
+// class shared_mutex;
+
+// void lock();
+
+#include <shared_mutex>
+#include <thread>
+#include <cstdlib>
+#include <cassert>
+
+
+std::shared_mutex m;
+
+typedef std::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef std::chrono::milliseconds ms;
+typedef std::chrono::nanoseconds ns;
+
+void f()
+{
+    time_point t0 = Clock::now();
+    m.lock();
+    time_point t1 = Clock::now();
+    m.unlock();
+    ns d = t1 - t0 - ms(250);
+    assert(d < ms(50));  // within 50ms
+}
+
+int main()
+{
+    m.lock();
+    std::thread t(f);
+    std::this_thread::sleep_for(ms(250));
+    m.unlock();
+    t.join();
+}

Added: libcxx/trunk/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/lock_shared.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/lock_shared.pass.cpp?rev=241067&view=auto
==============================================================================
--- libcxx/trunk/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/lock_shared.pass.cpp (added)
+++ libcxx/trunk/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/lock_shared.pass.cpp Tue Jun 30 09:04:14 2015
@@ -0,0 +1,73 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++03, c++98, c++11, c++14
+
+// <shared_mutex>
+
+// class shared_mutex;
+
+// void lock_shared();
+
+#include <shared_mutex>
+#include <thread>
+#include <vector>
+#include <cstdlib>
+#include <cassert>
+
+std::shared_mutex m;
+
+typedef std::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef std::chrono::milliseconds ms;
+typedef std::chrono::nanoseconds ns;
+
+void f()
+{
+    time_point t0 = Clock::now();
+    m.lock_shared();
+    time_point t1 = Clock::now();
+    m.unlock_shared();
+    ns d = t1 - t0 - ms(250);
+    assert(d < ms(50));  // within 50ms
+}
+
+void g()
+{
+    time_point t0 = Clock::now();
+    m.lock_shared();
+    time_point t1 = Clock::now();
+    m.unlock_shared();
+    ns d = t1 - t0;
+    assert(d < ms(50));  // within 50ms
+}
+
+
+int main()
+{
+    m.lock();
+    std::vector<std::thread> v;
+    for (int i = 0; i < 5; ++i)
+        v.push_back(std::thread(f));
+    std::this_thread::sleep_for(ms(250));
+    m.unlock();
+    for (auto& t : v)
+        t.join();
+    m.lock_shared();
+    for (auto& t : v)
+        t = std::thread(g);
+    std::thread q(f);
+    std::this_thread::sleep_for(ms(250));
+    m.unlock_shared();
+    for (auto& t : v)
+        t.join();
+    q.join();
+}

Added: libcxx/trunk/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/try_lock.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/try_lock.pass.cpp?rev=241067&view=auto
==============================================================================
--- libcxx/trunk/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/try_lock.pass.cpp (added)
+++ libcxx/trunk/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/try_lock.pass.cpp Tue Jun 30 09:04:14 2015
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++03, c++98, c++11, c++14
+
+// <shared_mutex>
+
+// class shared_mutex;
+
+// bool try_lock();
+
+#include <shared_mutex>
+#include <thread>
+#include <cstdlib>
+#include <cassert>
+
+std::shared_mutex m;
+
+typedef std::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef std::chrono::milliseconds ms;
+typedef std::chrono::nanoseconds ns;
+
+void f()
+{
+    time_point t0 = Clock::now();
+    assert(!m.try_lock());
+    assert(!m.try_lock());
+    assert(!m.try_lock());
+    while(!m.try_lock())
+        ;
+    time_point t1 = Clock::now();
+    m.unlock();
+    ns d = t1 - t0 - ms(250);
+    assert(d < ms(200));  // within 200ms
+}
+
+int main()
+{
+    m.lock();
+    std::thread t(f);
+    std::this_thread::sleep_for(ms(250));
+    m.unlock();
+    t.join();
+}

Added: libcxx/trunk/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/try_lock_shared.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/try_lock_shared.pass.cpp?rev=241067&view=auto
==============================================================================
--- libcxx/trunk/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/try_lock_shared.pass.cpp (added)
+++ libcxx/trunk/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/try_lock_shared.pass.cpp Tue Jun 30 09:04:14 2015
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++03, c++98, c++11, c++14
+
+// <shared_mutex>
+
+// class shared_mutex;
+
+// bool try_lock_shared();
+
+#include <shared_mutex>
+#include <thread>
+#include <vector>
+#include <cstdlib>
+#include <cassert>
+
+std::shared_mutex m;
+
+typedef std::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef std::chrono::milliseconds ms;
+typedef std::chrono::nanoseconds ns;
+
+void f()
+{
+    time_point t0 = Clock::now();
+    assert(!m.try_lock_shared());
+    assert(!m.try_lock_shared());
+    assert(!m.try_lock_shared());
+    while(!m.try_lock_shared())
+        ;
+    time_point t1 = Clock::now();
+    m.unlock_shared();
+    ns d = t1 - t0 - ms(250);
+    assert(d < ms(200));  // within 200ms
+}
+
+
+int main()
+{
+    m.lock();
+    std::vector<std::thread> v;
+    for (int i = 0; i < 5; ++i)
+        v.push_back(std::thread(f));
+    std::this_thread::sleep_for(ms(250));
+    m.unlock();
+    for (auto& t : v)
+        t.join();
+}





More information about the cfe-commits mailing list