[libcxx] r272634 - Implement variadic lock_guard.
Eric Fiselier via cfe-commits
cfe-commits at lists.llvm.org
Mon Jun 13 22:49:44 PDT 2016
This is causing some of the libc++ bots to go red. `variadic_copy.fail.cpp`
is encountering an error, which seems to be a clang bug which temporarily
existed in 3.9.
The test passes against current ToT and older clang releases and GCC.
Please do not revert this commit due to that specific failure. I am aware
of it and I am working to fix it.
On Mon, Jun 13, 2016 at 9:48 PM, Eric Fiselier via cfe-commits <
cfe-commits at lists.llvm.org> wrote:
> Author: ericwf
> Date: Mon Jun 13 22:48:09 2016
> New Revision: 272634
>
> URL: http://llvm.org/viewvc/llvm-project?rev=272634&view=rev
> Log:
> Implement variadic lock_guard.
>
> Summary:
> This patch implements the variadic `lock_guard` paper.
>
> Making `lock_guard` variadic is a ABI breaking change because the
> specialization `lock_guard<_Mutex>` mangles differently then when it was
> the primary template. This change only provides variadic `lock_guard` in
> ABI V2 or when `_LIBCPP_ABI_VARIADIC_LOCK_GUARD` is defined.
>
> Note that in ABI V2 `lock_guard` must always be declared as a variadic
> template, even in C++03, in order to keep the ABI consistent. For this
> reason `lock_guard` is forward declared as a variadic template in all
> standard dialects and therefore depends on variadic templates being
> provided as an extension in C++03. All supported versions of Clang and GCC
> provide this extension.
>
>
>
>
> Reviewers: mclow.lists
>
> Subscribers: K-ballo, mclow.lists, cfe-commits
>
> Differential Revision: http://reviews.llvm.org/D21260
>
> Added:
> libcxx/trunk/test/libcxx/thread/thread.mutex/thread.lock/
>
> libcxx/trunk/test/libcxx/thread/thread.mutex/thread.lock/thread.lock.guard/
>
> libcxx/trunk/test/libcxx/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex_mangling.pass.cpp
>
> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_adopt_lock.pass.cpp
>
> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_assign.fail.cpp
>
> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_copy.fail.cpp
>
> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.fail.cpp
>
> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.pass.cpp
>
> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex_cxx03.pass.cpp
>
> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_types.pass.cpp
> Modified:
> libcxx/trunk/include/__config
> libcxx/trunk/include/__mutex_base
> libcxx/trunk/include/mutex
>
> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.fail.cpp
> libcxx/trunk/www/cxx1z_status.html
>
> Modified: libcxx/trunk/include/__config
> URL:
> http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/__config?rev=272634&r1=272633&r2=272634&view=diff
>
> ==============================================================================
> --- libcxx/trunk/include/__config (original)
> +++ libcxx/trunk/include/__config Mon Jun 13 22:48:09 2016
> @@ -43,6 +43,7 @@
> #define _LIBCPP_ABI_LIST_REMOVE_NODE_POINTER_UB
> #define _LIBCPP_ABI_FORWARD_LIST_REMOVE_NODE_POINTER_UB
> #define _LIBCPP_ABI_FIX_UNORDERED_CONTAINER_SIZE_TYPE
> +#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD
> #endif
>
> #define _LIBCPP_CONCAT1(_LIBCPP_X,_LIBCPP_Y) _LIBCPP_X##_LIBCPP_Y
>
> Modified: libcxx/trunk/include/__mutex_base
> URL:
> http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/__mutex_base?rev=272634&r1=272633&r2=272634&view=diff
>
> ==============================================================================
> --- libcxx/trunk/include/__mutex_base (original)
> +++ libcxx/trunk/include/__mutex_base Mon Jun 13 22:48:09 2016
> @@ -76,8 +76,21 @@ constexpr adopt_lock_t adopt_lock = ad
>
> #endif
>
> +
> +// Forward declare lock_guard as a variadic template even in C++03 to keep
> +// the mangling consistent between dialects.
> +#if defined(_LIBCPP_ABI_VARIADIC_LOCK_GUARD)
> +template <class ..._Mutexes>
> +class _LIBCPP_TYPE_VIS_ONLY lock_guard;
> +#endif
> +
> template <class _Mutex>
> -class _LIBCPP_TYPE_VIS_ONLY
> _LIBCPP_THREAD_SAFETY_ANNOTATION(scoped_lockable) lock_guard
> +class _LIBCPP_TYPE_VIS_ONLY
> _LIBCPP_THREAD_SAFETY_ANNOTATION(scoped_lockable)
> +#if !defined(_LIBCPP_ABI_VARIADIC_LOCK_GUARD)
> +lock_guard
> +#else
> +lock_guard<_Mutex>
> +#endif
> {
> public:
> typedef _Mutex mutex_type;
> @@ -96,8 +109,8 @@ public:
> ~lock_guard() _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability())
> {__m_.unlock();}
>
> private:
> - lock_guard(lock_guard const&);// = delete;
> - lock_guard& operator=(lock_guard const&);// = delete;
> + lock_guard(lock_guard const&) _LIBCPP_EQUAL_DELETE;
> + lock_guard& operator=(lock_guard const&) _LIBCPP_EQUAL_DELETE;
> };
>
> template <class _Mutex>
>
> Modified: libcxx/trunk/include/mutex
> URL:
> http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/mutex?rev=272634&r1=272633&r2=272634&view=diff
>
> ==============================================================================
> --- libcxx/trunk/include/mutex (original)
> +++ libcxx/trunk/include/mutex Mon Jun 13 22:48:09 2016
> @@ -109,6 +109,19 @@ public:
> lock_guard& operator=(lock_guard const&) = delete;
> };
>
> +template <class... MutexTypes> // Variadic lock_guard only provided in
> ABI V2.
> +class lock_guard
> +{
> +public:
> + explicit lock_guard(MutexTypes&... m);
> + lock_guard(MutexTypes&... m, adopt_lock_t);
> + ~lock_guard();
> + lock_guard(lock_guard const&) = delete;
> + lock_guard& operator=(lock_guard const&) = delete;
> +private:
> + tuple<MutexTypes&...> pm; // exposition only
> +};
> +
> template <class Mutex>
> class unique_lock
> {
> @@ -427,6 +440,27 @@ lock(_L0& __l0, _L1& __l1, _L2& __l2, _L
> __lock_first(0, __l0, __l1, __l2, __l3...);
> }
>
> +template <class _L0>
> +inline _LIBCPP_INLINE_VISIBILITY
> +void __unlock(_L0& __l0) {
> + __l0.unlock();
> +}
> +
> +template <class _L0, class _L1>
> +inline _LIBCPP_INLINE_VISIBILITY
> +void __unlock(_L0& __l0, _L1& __l1) {
> + __l0.unlock();
> + __l1.unlock();
> +}
> +
> +template <class _L0, class _L1, class _L2, class ..._L3>
> +inline _LIBCPP_INLINE_VISIBILITY
> +void __unlock(_L0& __l0, _L1& __l1, _L2& __l2, _L3&... __l3) {
> + __l0.unlock();
> + __l1.unlock();
> + _VSTD::__unlock(__l2, __l3...);
> +}
> +
> #endif // _LIBCPP_HAS_NO_VARIADICS
>
> #endif // !_LIBCPP_HAS_NO_THREADS
> @@ -577,6 +611,63 @@ call_once(once_flag& __flag, const _Call
>
> #endif // _LIBCPP_HAS_NO_VARIADICS
>
> +
> +#if defined(_LIBCPP_ABI_VARIADIC_LOCK_GUARD) \
> + && !defined(_LIBCPP_CXX03_LANG)
> +template <>
> +class _LIBCPP_TYPE_VIS_ONLY lock_guard<> {
> +public:
> + explicit lock_guard() = default;
> + ~lock_guard() = default;
> +
> + _LIBCPP_INLINE_VISIBILITY
> + explicit lock_guard(adopt_lock_t) {}
> +
> + lock_guard(lock_guard const&) = delete;
> + lock_guard& operator=(lock_guard const&) = delete;
> +};
> +
> +template <class ..._MArgs>
> +class _LIBCPP_TYPE_VIS_ONLY lock_guard
> +{
> + static_assert(sizeof...(_MArgs) >= 2, "At least 2 lock types
> required");
> + typedef tuple<_MArgs&...> _MutexTuple;
> +
> +public:
> + _LIBCPP_INLINE_VISIBILITY
> + explicit lock_guard(_MArgs&... __margs)
> + : __t_(__margs...)
> + {
> + _VSTD::lock(__margs...);
> + }
> +
> + _LIBCPP_INLINE_VISIBILITY
> + lock_guard(_MArgs&... __margs, adopt_lock_t)
> + : __t_(__margs...)
> + {
> + }
> +
> + _LIBCPP_INLINE_VISIBILITY
> + ~lock_guard() {
> + typedef typename __make_tuple_indices<sizeof...(_MArgs)>::type
> _Indices;
> + __unlock_unpack(_Indices{}, __t_);
> + }
> +
> + lock_guard(lock_guard const&) = delete;
> + lock_guard& operator=(lock_guard const&) = delete;
> +
> +private:
> + template <size_t ..._Indx>
> + _LIBCPP_INLINE_VISIBILITY
> + static void __unlock_unpack(__tuple_indices<_Indx...>, _MutexTuple&
> __mt) {
> + _VSTD::__unlock(_VSTD::get<_Indx>(__mt)...);
> + }
> +
> + _MutexTuple __t_;
> +};
> +
> +#endif // _LIBCPP_ABI_VARIADIC_LOCK_GUARD
> +
> _LIBCPP_END_NAMESPACE_STD
>
> #endif // _LIBCPP_MUTEX
>
> Added:
> libcxx/trunk/test/libcxx/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex_mangling.pass.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/libcxx/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex_mangling.pass.cpp?rev=272634&view=auto
>
> ==============================================================================
> ---
> libcxx/trunk/test/libcxx/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex_mangling.pass.cpp
> (added)
> +++
> libcxx/trunk/test/libcxx/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex_mangling.pass.cpp
> Mon Jun 13 22:48:09 2016
> @@ -0,0 +1,31 @@
>
> +//===----------------------------------------------------------------------===//
> +//
> +// 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
> +
> +// THIS TESTS C++03 EXTENSIONS.
> +
> +// <mutex>
> +
> +// template <class ...Mutex> class lock_guard;
> +
> +// Test that the the variadic lock guard implementation mangles the same
> in
> +// C++11 and C++03. This is important since the mangling of `lock_guard`
> depends
> +// on it being declared as a variadic template, even in C++03.
> +
> +#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD
> +#include <mutex>
> +#include <typeinfo>
> +#include <cassert>
> +#include <iostream>
> +
> +int main() {
> + const std::string expect = "NSt3__110lock_guardIJNS_5mutexEEEE";
> + assert(typeid(std::lock_guard<std::mutex>).name() == expect);
> +}
>
> Modified:
> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.fail.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.fail.cpp?rev=272634&r1=272633&r2=272634&view=diff
>
> ==============================================================================
> ---
> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.fail.cpp
> (original)
> +++
> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.fail.cpp
> Mon Jun 13 22:48:09 2016
> @@ -7,6 +7,8 @@
> //
>
> //===----------------------------------------------------------------------===//
>
> +// UNSUPPORTED: libcpp-has-no-threads
> +
> // <mutex>
>
> // template <class Mutex> class lock_guard;
> @@ -14,35 +16,9 @@
> // explicit lock_guard(mutex_type& m);
>
> #include <mutex>
> -#include <thread>
> -#include <cstdlib>
> -#include <cassert>
> -
> -std::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();
> - time_point t1;
> - {
> - std::lock_guard<std::mutex> lg = m;
> - t1 = Clock::now();
> - }
> - ns d = t1 - t0 - ms(250);
> - assert(d < ns(2500000)); // within 2.5ms
> -}
>
> int main()
> {
> - m.lock();
> - std::thread t(f);
> - std::this_thread::sleep_for(ms(250));
> - m.unlock();
> - t.join();
> + std::mutex m;
> + std::lock_guard<std::mutex> lg = m; // expected-error{{no viable
> conversion}}
> }
>
> Added:
> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_adopt_lock.pass.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_adopt_lock.pass.cpp?rev=272634&view=auto
>
> ==============================================================================
> ---
> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_adopt_lock.pass.cpp
> (added)
> +++
> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_adopt_lock.pass.cpp
> Mon Jun 13 22:48:09 2016
> @@ -0,0 +1,62 @@
>
> +//===----------------------------------------------------------------------===//
> +//
> +// 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++98, c++03
> +
> +// <mutex>
> +
> +// template <class ...Mutex> class lock_guard;
> +
> +// lock_guard(Mutex&..., adopt_lock_t);
> +
> +#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD
> +#include <mutex>
> +#include <cassert>
> +
> +struct TestMutex {
> + bool locked = false;
> + TestMutex() = default;
> +
> + void lock() { assert(!locked); locked = true; }
> + bool try_lock() { if (locked) return false; return locked = true; }
> + void unlock() { assert(locked); locked = false; }
> +
> + TestMutex(TestMutex const&) = delete;
> + TestMutex& operator=(TestMutex const&) = delete;
> +};
> +
> +int main()
> +{
> + {
> + using LG = std::lock_guard<>;
> + LG lg(std::adopt_lock);
> + }
> + {
> + TestMutex m1, m2;
> + using LG = std::lock_guard<TestMutex, TestMutex>;
> + m1.lock(); m2.lock();
> + {
> + LG lg(m1, m2, std::adopt_lock);
> + assert(m1.locked && m2.locked);
> + }
> + assert(!m1.locked && !m2.locked);
> + }
> + {
> + TestMutex m1, m2, m3;
> + using LG = std::lock_guard<TestMutex, TestMutex, TestMutex>;
> + m1.lock(); m2.lock(); m3.lock();
> + {
> + LG lg(m1, m2, m3, std::adopt_lock);
> + assert(m1.locked && m2.locked && m3.locked);
> + }
> + assert(!m1.locked && !m2.locked && !m3.locked);
> + }
> +
> +}
>
> Added:
> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_assign.fail.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_assign.fail.cpp?rev=272634&view=auto
>
> ==============================================================================
> ---
> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_assign.fail.cpp
> (added)
> +++
> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_assign.fail.cpp
> Mon Jun 13 22:48:09 2016
> @@ -0,0 +1,44 @@
>
> +//===----------------------------------------------------------------------===//
> +//
> +// 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++98, c++03
> +
> +// <mutex>
> +
> +// template <class ...Mutex> class lock_guard;
> +
> +// lock_guard& operator=(lock_guard const&) = delete;
> +
> +#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD
> +#include <mutex>
> +
> +int main()
> +{
> + using M = std::mutex;
> + M m0, m1, m2;
> + M om0, om1, om2;
> + {
> + using LG = std::lock_guard<>;
> + LG lg1, lg2;
> + lg1 = lg2; // expected-error{{overload resolution selected
> deleted operator '='}}
> + }
> + {
> + using LG = std::lock_guard<M, M>;
> + LG lg1(m0, m1);
> + LG lg2(om0, om1);
> + lg1 = lg2; // expected-error{{overload resolution selected
> deleted operator '='}}
> + }
> + {
> + using LG = std::lock_guard<M, M, M>;
> + LG lg1(m0, m1, m2);
> + LG lg2(om0, om1, om2);
> + lg1 = lg2; // expected-error{{overload resolution selected
> deleted operator '='}}
> + }
> +}
>
> Added:
> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_copy.fail.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_copy.fail.cpp?rev=272634&view=auto
>
> ==============================================================================
> ---
> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_copy.fail.cpp
> (added)
> +++
> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_copy.fail.cpp
> Mon Jun 13 22:48:09 2016
> @@ -0,0 +1,41 @@
>
> +//===----------------------------------------------------------------------===//
> +//
> +// 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++98, c++03
> +
> +// <mutex>
> +
> +// template <class ...Mutex> class lock_guard;
> +
> +// lock_guard(lock_guard const&) = delete;
> +
> +#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD
> +#include <mutex>
> +
> +int main()
> +{
> + using M = std::mutex;
> + M m0, m1, m2;
> + {
> + using LG = std::lock_guard<>;
> + const LG Orig;
> + LG Copy(Orig); // expected-error{{call to deleted constructor of
> 'LG'}}
> + }
> + {
> + using LG = std::lock_guard<M, M>;
> + const LG Orig(m0, m1);
> + LG Copy(Orig); // expected-error{{call to deleted constructor of
> 'LG'}}
> + }
> + {
> + using LG = std::lock_guard<M, M, M>;
> + const LG Orig(m0, m1, m2);
> + LG Copy(Orig); // expected-error{{call to deleted constructor of
> 'LG'}}
> + }
> +}
>
> Added:
> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.fail.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.fail.cpp?rev=272634&view=auto
>
> ==============================================================================
> ---
> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.fail.cpp
> (added)
> +++
> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.fail.cpp
> Mon Jun 13 22:48:09 2016
> @@ -0,0 +1,47 @@
>
> +//===----------------------------------------------------------------------===//
> +//
> +// 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++98, c++03
> +
> +// <mutex>
> +
> +// template <class ...Mutex> class lock_guard;
> +
> +// explicit lock_guard(Mutex&...);
> +
> +#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD
> +#include <mutex>
> +
> +template <class LG>
> +void test_conversion(LG) {}
> +
> +int main()
> +{
> + using M = std::mutex;
> + M m0, m1, m2;
> + M n0, n1, n2;
> + {
> + using LG = std::lock_guard<>;
> + LG lg = {}; // expected-error{{chosen constructor is explicit in
> copy-initialization}}
> + test_conversion<LG>({}); // expected-error{{no matching function
> for call}}
> + ((void)lg);
> + }
> + {
> + using LG = std::lock_guard<M, M>;
> + LG lg = {m0, m1}; // expected-error{{chosen constructor is
> explicit in copy-initialization}}
> + test_conversion<LG>({n0, n1}); // expected-error{{no matching
> function for call}}
> + ((void)lg);
> + }
> + {
> + using LG = std::lock_guard<M, M, M>;
> + LG lg = {m0, m1, m2}; // expected-error{{chosen constructor is
> explicit in copy-initialization}}
> + test_conversion<LG>({n0, n1, n2}); // expected-error{{no matching
> function for call}}
> + }
> +}
>
> Added:
> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.pass.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.pass.cpp?rev=272634&view=auto
>
> ==============================================================================
> ---
> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.pass.cpp
> (added)
> +++
> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.pass.cpp
> Mon Jun 13 22:48:09 2016
> @@ -0,0 +1,113 @@
>
> +//===----------------------------------------------------------------------===//
> +//
> +// 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++98, c++03
> +
> +// <mutex>
> +
> +// template <class ...Mutex> class lock_guard;
> +
> +// explicit lock_guard(mutex_type& m);
> +
> +#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD
> +#include <mutex>
> +#include <cassert>
> +
> +struct TestMutex {
> + bool locked = false;
> + TestMutex() = default;
> + ~TestMutex() { assert(!locked); }
> +
> + void lock() { assert(!locked); locked = true; }
> + bool try_lock() { if (locked) return false; return locked = true; }
> + void unlock() { assert(locked); locked = false; }
> +
> + TestMutex(TestMutex const&) = delete;
> + TestMutex& operator=(TestMutex const&) = delete;
> +};
> +
> +#if !defined(TEST_HAS_NO_EXCEPTIONS)
> +struct TestMutexThrows {
> + bool locked = false;
> + bool throws_on_lock = false;
> +
> + TestMutexThrows() = default;
> + ~TestMutexThrows() { assert(!locked); }
> +
> + void lock() {
> + assert(!locked);
> + if (throws_on_lock) {
> + throw 42;
> + }
> + locked = true;
> + }
> +
> + bool try_lock() {
> + if (locked) return false;
> + lock();
> + return true;
> + }
> +
> + void unlock() { assert(locked); locked = false; }
> +
> + TestMutexThrows(TestMutexThrows const&) = delete;
> + TestMutexThrows& operator=(TestMutexThrows const&) = delete;
> +};
> +#endif // !defined(TEST_HAS_NO_EXCEPTIONS)
> +
> +int main()
> +{
> + {
> + using LG = std::lock_guard<>;
> + LG lg;
> + }
> + {
> + using LG = std::lock_guard<TestMutex, TestMutex>;
> + TestMutex m1, m2;
> + {
> + LG lg(m1, m2);
> + assert(m1.locked && m2.locked);
> + }
> + assert(!m1.locked && !m2.locked);
> + }
> + {
> + using LG = std::lock_guard<TestMutex, TestMutex, TestMutex>;
> + TestMutex m1, m2, m3;
> + {
> + LG lg(m1, m2, m3);
> + assert(m1.locked && m2.locked && m3.locked);
> + }
> + assert(!m1.locked && !m2.locked && !m3.locked);
> + }
> +#if !defined(TEST_HAS_NO_EXCEPTIONS)
> + {
> + using MT = TestMutexThrows;
> + using LG = std::lock_guard<MT, MT>;
> + MT m1, m2;
> + m1.throws_on_lock = true;
> + try {
> + LG lg(m1, m2);
> + assert(false);
> + } catch (int) {}
> + assert(!m1.locked && !m2.locked);
> + }
> + {
> + using MT = TestMutexThrows;
> + using LG = std::lock_guard<MT, MT, MT>;
> + MT m1, m2, m3;
> + m2.throws_on_lock = true;
> + try {
> + LG lg(m1, m2, m3);
> + assert(false);
> + } catch (int) {}
> + assert(!m1.locked && !m2.locked && !m3.locked);
> + }
> +#endif
> +}
>
> Added:
> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex_cxx03.pass.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex_cxx03.pass.cpp?rev=272634&view=auto
>
> ==============================================================================
> ---
> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex_cxx03.pass.cpp
> (added)
> +++
> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex_cxx03.pass.cpp
> Mon Jun 13 22:48:09 2016
> @@ -0,0 +1,21 @@
>
> +//===----------------------------------------------------------------------===//
> +//
> +// 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
> +
> +// <mutex>
> +
> +// template <class ...Mutex> class lock_guard;
> +
> +// Test that the variadic lock guard implementation compiles in all
> standard
> +// dialects, including C++03, even though it is forward declared using
> +// variadic templates.
> +
> +#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD
> +#include "mutex.pass.cpp" // Use the existing non-variadic test
>
> Added:
> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_types.pass.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_types.pass.cpp?rev=272634&view=auto
>
> ==============================================================================
> ---
> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_types.pass.cpp
> (added)
> +++
> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_types.pass.cpp
> Mon Jun 13 22:48:09 2016
> @@ -0,0 +1,78 @@
>
> +//===----------------------------------------------------------------------===//
> +//
> +// 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++98, c++03
> +
> +// <mutex>
> +
> +// template <class Mutex>
> +// class lock_guard
> +// {
> +// public:
> +// typedef Mutex mutex_type;
> +// ...
> +// };
> +
> +#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD
> +#include <mutex>
> +#include <type_traits>
> +
> +struct NAT {};
> +
> +template <class LG>
> +auto test_typedef(int) -> typename LG::mutex_type;
> +
> +template <class LG>
> +auto test_typedef(...) -> NAT;
> +
> +template <class LG>
> +constexpr bool has_mutex_type() {
> + return !std::is_same<decltype(test_typedef<LG>(0)), NAT>::value;
> +}
> +
> +int main()
> +{
> + {
> + using T = std::lock_guard<>;
> + static_assert(!has_mutex_type<T>(), "");
> + }
> + {
> + using M1 = std::mutex;
> + using T = std::lock_guard<M1>;
> + static_assert(std::is_same<T::mutex_type, M1>::value, "");
> + }
> + {
> + using M1 = std::recursive_mutex;
> + using T = std::lock_guard<M1>;
> + static_assert(std::is_same<T::mutex_type, M1>::value, "");
> + }
> + {
> + using M1 = std::mutex;
> + using M2 = std::recursive_mutex;
> + using T = std::lock_guard<M1, M2>;
> + static_assert(!has_mutex_type<T>(), "");
> + }
> + {
> + using M1 = std::mutex;
> + using M2 = std::recursive_mutex;
> + using T = std::lock_guard<M1, M1, M2>;
> + static_assert(!has_mutex_type<T>(), "");
> + }
> + {
> + using M1 = std::mutex;
> + using T = std::lock_guard<M1, M1>;
> + static_assert(!has_mutex_type<T>(), "");
> + }
> + {
> + using M1 = std::recursive_mutex;
> + using T = std::lock_guard<M1, M1, M1>;
> + static_assert(!has_mutex_type<T>(), "");
> + }
> +}
>
> Modified: libcxx/trunk/www/cxx1z_status.html
> URL:
> http://llvm.org/viewvc/llvm-project/libcxx/trunk/www/cxx1z_status.html?rev=272634&r1=272633&r2=272634&view=diff
>
> ==============================================================================
> --- libcxx/trunk/www/cxx1z_status.html (original)
> +++ libcxx/trunk/www/cxx1z_status.html Mon Jun 13 22:48:09 2016
> @@ -74,7 +74,7 @@
> <tr><td><a href="
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/P0006R0.html">P0006R0</a></td><td>LWG</td><td>Adopt
> Type Traits Variable Templates for
> C++17.</td><td>Kona</td><td>Complete</td><td>3.8</td></tr>
> <tr><td><a href="
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/P0092R1.html">P0092R1</a></td><td>LWG</td><td>Polishing
> <chrono></td><td>Kona</td><td>Complete</td><td>3.8</td></tr>
> <tr><td><a href="
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/P0007R1.html">P0007R1</a></td><td>LWG</td><td>Constant
> View: A proposal for a <tt>std::as_const</tt> helper function
> template.</td><td>Kona</td><td>Complete</td><td>3.8</td></tr>
> - <tr><td><a href="
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/P0156R0.htm"
> >P0156R0</a></td><td>LWG</td><td>Variadic lock_guard(rev
> 3).</td><td>Kona</td><td></td><td></td></tr>
> + <tr><td><a href="
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0156r0.html"
> >P0156R0</a></td><td>LWG</td><td>Variadic lock_guard(rev
> 3).</td><td>Kona</td><td>Complete (ABI V2 Only)</td><td>3.9</td></tr>
> <tr><td><a href="
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/P0074R0.html">P0074R0</a></td><td>LWG</td><td>Making
> <tt>std::owner_less</tt> more
> flexible</td><td>Kona</td><td>Complete</td><td>3.8</td></tr>
> <tr><td><a href="
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/P0013R1.html">P0013R1</a></td><td>LWG</td><td>Logical
> type traits rev 2</td><td>Kona</td><td>Complete</td><td>3.8</td></tr>
> <tr><td></td><td></td><td></td><td></td><td></td><td></td></tr>
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160613/e35a25b5/attachment-0001.html>
More information about the cfe-commits
mailing list