diff options
Diffstat (limited to 'include/mutex')
-rw-r--r-- | include/mutex | 113 |
1 files changed, 101 insertions, 12 deletions
diff --git a/include/mutex b/include/mutex index a0875a568ec67..c047cf943e8ce 100644 --- a/include/mutex +++ b/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 { @@ -179,9 +192,7 @@ template<class Callable, class ...Args> #ifndef _LIBCPP_HAS_NO_VARIADICS #include <tuple> #endif -#ifndef _LIBCPP_HAS_NO_THREADS -#include <sched.h> -#endif +#include <__threading_support> #include <__undef_min_max> @@ -195,7 +206,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD class _LIBCPP_TYPE_VIS recursive_mutex { - pthread_mutex_t __m_; + __libcpp_mutex_t __m_; public: recursive_mutex(); @@ -210,7 +221,7 @@ public: bool try_lock() _NOEXCEPT; void unlock() _NOEXCEPT; - typedef pthread_mutex_t* native_handle_type; + typedef __libcpp_mutex_t* native_handle_type; _LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() {return &__m_;} }; @@ -262,7 +273,7 @@ class _LIBCPP_TYPE_VIS recursive_timed_mutex mutex __m_; condition_variable __cv_; size_t __count_; - pthread_t __id_; + __libcpp_thread_id __id_; public: recursive_timed_mutex(); ~recursive_timed_mutex(); @@ -288,9 +299,9 @@ bool recursive_timed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) { using namespace chrono; - pthread_t __id = pthread_self(); + __libcpp_thread_id __id = __libcpp_thread_get_current_id(); unique_lock<mutex> lk(__m_); - if (pthread_equal(__id, __id_)) + if (__libcpp_thread_id_equal(__id, __id_)) { if (__count_ == numeric_limits<size_t>::max()) return false; @@ -362,7 +373,7 @@ lock(_L0& __l0, _L1& __l1) break; } } - sched_yield(); + __libcpp_thread_yield(); { unique_lock<_L1> __u1(__l1); if (__l0.try_lock()) @@ -371,7 +382,7 @@ lock(_L0& __l0, _L1& __l1) break; } } - sched_yield(); + __libcpp_thread_yield(); } } @@ -396,7 +407,7 @@ __lock_first(int __i, _L0& __l0, _L1& __l1, _L2& __l2, _L3& ...__l3) } } ++__i; - sched_yield(); + __libcpp_thread_yield(); break; case 1: { @@ -412,7 +423,7 @@ __lock_first(int __i, _L0& __l0, _L1& __l1, _L2& __l2, _L3& ...__l3) __i = 0; else __i += 2; - sched_yield(); + __libcpp_thread_yield(); break; default: __lock_first(__i - 2, __l2, __l3..., __l0, __l1); @@ -429,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 @@ -579,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() {} + ~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 |