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(); +} _______________________________________________ cfe-commits mailing list cfe-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits