[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