summaryrefslogtreecommitdiff
path: root/include/mutex
diff options
context:
space:
mode:
Diffstat (limited to 'include/mutex')
-rw-r--r--include/mutex113
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