diff options
| author | Eric Fiselier <eric@efcs.ca> | 2016-06-14 03:48:09 +0000 |
|---|---|---|
| committer | Eric Fiselier <eric@efcs.ca> | 2016-06-14 03:48:09 +0000 |
| commit | 48f35e074e4aca420bd8d58f757f862cd998a9b7 (patch) | |
| tree | 6ace79c4eaeef6778912d2abe104714103de9f75 /libcxx/include/mutex | |
| parent | 9778a6d811c346eb9cdd8b6c6c28a915e58d1b67 (diff) | |
| download | bcm5719-llvm-48f35e074e4aca420bd8d58f757f862cd998a9b7.tar.gz bcm5719-llvm-48f35e074e4aca420bd8d58f757f862cd998a9b7.zip | |
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
llvm-svn: 272634
Diffstat (limited to 'libcxx/include/mutex')
| -rw-r--r-- | libcxx/include/mutex | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/libcxx/include/mutex b/libcxx/include/mutex index 4d288ae1fc9..1d038b59fc3 100644 --- a/libcxx/include/mutex +++ b/libcxx/include/mutex @@ -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, _L3& ...__l3) __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 _Callable& __func) #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 |

