summaryrefslogtreecommitdiffstats
path: root/libcxx/include/mutex
diff options
context:
space:
mode:
authorEric Fiselier <eric@efcs.ca>2016-06-14 03:48:09 +0000
committerEric Fiselier <eric@efcs.ca>2016-06-14 03:48:09 +0000
commit48f35e074e4aca420bd8d58f757f862cd998a9b7 (patch)
tree6ace79c4eaeef6778912d2abe104714103de9f75 /libcxx/include/mutex
parent9778a6d811c346eb9cdd8b6c6c28a915e58d1b67 (diff)
downloadbcm5719-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/mutex91
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
OpenPOWER on IntegriCloud