| // -*- C++ -*- | 
 | //===--------------------------- mutex ------------------------------------===// | 
 | // | 
 | //                     The LLVM Compiler Infrastructure | 
 | // | 
 | // This file is distributed under the University of Illinois Open Source | 
 | // License. See LICENSE.TXT for details. | 
 | // | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | #ifndef _LIBCPP_MUTEX | 
 | #define _LIBCPP_MUTEX | 
 |  | 
 | /* | 
 |     mutex synopsis | 
 |  | 
 | namespace std | 
 | { | 
 |  | 
 | class mutex | 
 | { | 
 | public: | 
 |      mutex(); | 
 |      ~mutex(); | 
 |  | 
 |     mutex(const mutex&) = delete; | 
 |     mutex& operator=(const mutex&) = delete; | 
 |  | 
 |     void lock(); | 
 |     bool try_lock(); | 
 |     void unlock(); | 
 |  | 
 |     typedef pthread_mutex_t* native_handle_type; | 
 |     native_handle_type native_handle(); | 
 | }; | 
 |  | 
 | class recursive_mutex | 
 | { | 
 | public: | 
 |      recursive_mutex(); | 
 |      ~recursive_mutex(); | 
 |  | 
 |     recursive_mutex(const recursive_mutex&) = delete; | 
 |     recursive_mutex& operator=(const recursive_mutex&) = delete; | 
 |  | 
 |     void lock(); | 
 |     bool try_lock(); | 
 |     void unlock(); | 
 |  | 
 |     typedef pthread_mutex_t* native_handle_type; | 
 |     native_handle_type native_handle(); | 
 | }; | 
 |  | 
 | class timed_mutex | 
 | { | 
 | public: | 
 |      timed_mutex(); | 
 |      ~timed_mutex(); | 
 |  | 
 |     timed_mutex(const timed_mutex&) = delete; | 
 |     timed_mutex& operator=(const timed_mutex&) = delete; | 
 |  | 
 |     void lock(); | 
 |     bool try_lock(); | 
 |     template <class Rep, class Period> | 
 |         bool try_lock_for(const chrono::duration<Rep, Period>& rel_time); | 
 |     template <class Clock, class Duration> | 
 |         bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time); | 
 |     void unlock(); | 
 | }; | 
 |  | 
 | class recursive_timed_mutex | 
 | { | 
 | public: | 
 |      recursive_timed_mutex(); | 
 |      ~recursive_timed_mutex(); | 
 |  | 
 |     recursive_timed_mutex(const recursive_timed_mutex&) = delete; | 
 |     recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete; | 
 |  | 
 |     void lock(); | 
 |     bool try_lock(); | 
 |     template <class Rep, class Period> | 
 |         bool try_lock_for(const chrono::duration<Rep, Period>& rel_time); | 
 |     template <class Clock, class Duration> | 
 |         bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time); | 
 |     void unlock(); | 
 | }; | 
 |  | 
 | struct defer_lock_t {}; | 
 | struct try_to_lock_t {}; | 
 | struct adopt_lock_t {}; | 
 |  | 
 | constexpr defer_lock_t  defer_lock{}; | 
 | constexpr try_to_lock_t try_to_lock{}; | 
 | constexpr adopt_lock_t  adopt_lock{}; | 
 |  | 
 | template <class Mutex> | 
 | class lock_guard | 
 | { | 
 | public: | 
 |     typedef Mutex mutex_type; | 
 |  | 
 |     explicit lock_guard(mutex_type& m); | 
 |     lock_guard(mutex_type& m, adopt_lock_t); | 
 |     ~lock_guard(); | 
 |  | 
 |     lock_guard(lock_guard const&) = delete; | 
 |     lock_guard& operator=(lock_guard const&) = delete; | 
 | }; | 
 |  | 
 | template <class Mutex> | 
 | class unique_lock | 
 | { | 
 | public: | 
 |     typedef Mutex mutex_type; | 
 |     unique_lock(); | 
 |     explicit unique_lock(mutex_type& m); | 
 |     unique_lock(mutex_type& m, defer_lock_t); | 
 |     unique_lock(mutex_type& m, try_to_lock_t); | 
 |     unique_lock(mutex_type& m, adopt_lock_t); | 
 |     template <class Clock, class Duration> | 
 |         unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time); | 
 |     template <class Rep, class Period> | 
 |         unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time); | 
 |     ~unique_lock(); | 
 |  | 
 |     unique_lock(unique_lock const&) = delete; | 
 |     unique_lock& operator=(unique_lock const&) = delete; | 
 |  | 
 |     unique_lock(unique_lock&& u); | 
 |     unique_lock& operator=(unique_lock&& u); | 
 |  | 
 |     void lock(); | 
 |     bool try_lock(); | 
 |  | 
 |     template <class Rep, class Period> | 
 |         bool try_lock_for(const chrono::duration<Rep, Period>& rel_time); | 
 |     template <class Clock, class Duration> | 
 |         bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time); | 
 |  | 
 |     void unlock(); | 
 |  | 
 |     void swap(unique_lock& u); | 
 |     mutex_type* release(); | 
 |  | 
 |     bool owns_lock() const; | 
 |     explicit operator bool () const; | 
 |     mutex_type* mutex() const; | 
 | }; | 
 |  | 
 | template <class Mutex> | 
 |   void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y); | 
 |  | 
 | template <class L1, class L2, class... L3> | 
 |   int try_lock(L1&, L2&, L3&...); | 
 | template <class L1, class L2, class... L3> | 
 |   void lock(L1&, L2&, L3&...); | 
 |  | 
 | struct once_flag | 
 | { | 
 |     constexpr once_flag(); | 
 |  | 
 |     once_flag(const once_flag&) = delete; | 
 |     once_flag& operator=(const once_flag&) = delete; | 
 | }; | 
 |  | 
 | template<class Callable, class ...Args> | 
 |   void call_once(once_flag& flag, Callable&& func, Args&&... args); | 
 |  | 
 | }  // std | 
 |  | 
 | */ | 
 |  | 
 | #include <__config> | 
 | #include <__mutex_base> | 
 | #include <functional> | 
 |  | 
 | #pragma GCC system_header | 
 |  | 
 | _LIBCPP_BEGIN_NAMESPACE_STD | 
 |  | 
 | class recursive_mutex | 
 | { | 
 |     pthread_mutex_t __m_; | 
 |  | 
 | public: | 
 |      recursive_mutex(); | 
 |      ~recursive_mutex(); | 
 |  | 
 | private: | 
 |     recursive_mutex(const recursive_mutex&); // = delete; | 
 |     recursive_mutex& operator=(const recursive_mutex&); // = delete; | 
 |  | 
 | public: | 
 |     void lock(); | 
 |     bool try_lock(); | 
 |     void unlock(); | 
 |  | 
 |     typedef pthread_mutex_t* native_handle_type; | 
 |     native_handle_type native_handle() {return &__m_;} | 
 | }; | 
 |  | 
 | class timed_mutex | 
 | { | 
 |     mutex              __m_; | 
 |     condition_variable __cv_; | 
 |     bool               __locked_; | 
 | public: | 
 |      timed_mutex(); | 
 |      ~timed_mutex(); | 
 |  | 
 | private: | 
 |     timed_mutex(const timed_mutex&); // = delete; | 
 |     timed_mutex& operator=(const timed_mutex&); // = delete; | 
 |  | 
 | public: | 
 |     void lock(); | 
 |     bool try_lock(); | 
 |     template <class _Rep, class _Period> | 
 |         bool try_lock_for(const chrono::duration<_Rep, _Period>& __d) | 
 |             {return try_lock_until(chrono::monotonic_clock::now() + __d);} | 
 |     template <class _Clock, class _Duration> | 
 |         bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t); | 
 |     void unlock(); | 
 | }; | 
 |  | 
 | template <class _Clock, class _Duration> | 
 | bool | 
 | timed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) | 
 | { | 
 |     using namespace chrono; | 
 |     unique_lock<mutex> __lk(__m_); | 
 |     bool no_timeout = _Clock::now() < __t; | 
 |     while (no_timeout && __locked_) | 
 |         no_timeout = __cv_.wait_until(__lk, __t) == cv_status::no_timeout; | 
 |     if (!__locked_) | 
 |     { | 
 |         __locked_ = true; | 
 |         return true; | 
 |     } | 
 |     return false; | 
 | } | 
 |  | 
 | class recursive_timed_mutex | 
 | { | 
 |     mutex              __m_; | 
 |     condition_variable __cv_; | 
 |     size_t             __count_; | 
 |     pthread_t          __id_; | 
 | public: | 
 |      recursive_timed_mutex(); | 
 |      ~recursive_timed_mutex(); | 
 |  | 
 | private: | 
 |     recursive_timed_mutex(const recursive_timed_mutex&); // = delete; | 
 |     recursive_timed_mutex& operator=(const recursive_timed_mutex&); // = delete; | 
 |  | 
 | public: | 
 |     void lock(); | 
 |     bool try_lock(); | 
 |     template <class _Rep, class _Period> | 
 |         bool try_lock_for(const chrono::duration<_Rep, _Period>& __d) | 
 |             {return try_lock_until(chrono::monotonic_clock::now() + __d);} | 
 |     template <class _Clock, class _Duration> | 
 |         bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t); | 
 |     void unlock(); | 
 | }; | 
 |  | 
 | template <class _Clock, class _Duration> | 
 | bool | 
 | recursive_timed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) | 
 | { | 
 |     using namespace chrono; | 
 |     pthread_t __id = pthread_self(); | 
 |     unique_lock<mutex> lk(__m_); | 
 |     if (pthread_equal(__id, __id_)) | 
 |     { | 
 |         if (__count_ == numeric_limits<size_t>::max()) | 
 |             return false; | 
 |         ++__count_; | 
 |         return true; | 
 |     } | 
 |     bool no_timeout = _Clock::now() < __t; | 
 |     while (no_timeout && __count_ != 0) | 
 |         no_timeout = __cv_.wait_until(lk, __t) == cv_status::no_timeout; | 
 |     if (__count_ == 0) | 
 |     { | 
 |         __count_ = 1; | 
 |         __id_ = __id; | 
 |         return true; | 
 |     } | 
 |     return false; | 
 | } | 
 |  | 
 | template <class _L0, class _L1> | 
 | int | 
 | try_lock(_L0& __l0, _L1& __l1) | 
 | { | 
 |     unique_lock<_L0> __u0(__l0, try_to_lock); | 
 |     if (__u0.owns_lock()) | 
 |     { | 
 |         if (__l1.try_lock()) | 
 |         { | 
 |             __u0.release(); | 
 |             return -1; | 
 |         } | 
 |         else | 
 |             return 1; | 
 |     } | 
 |     return 0; | 
 | } | 
 |  | 
 | #ifndef _LIBCPP_HAS_NO_VARIADICS | 
 |  | 
 | template <class _L0, class _L1, class _L2, class... _L3> | 
 | int | 
 | try_lock(_L0& __l0, _L1& __l1, _L2& __l2, _L3&... __l3) | 
 | { | 
 |     int __r = 0; | 
 |     unique_lock<_L0> __u0(__l0, try_to_lock); | 
 |     if (__u0.owns_lock()) | 
 |     { | 
 |         __r = try_lock(__l1, __l2, __l3...); | 
 |         if (__r == -1) | 
 |             __u0.release(); | 
 |         else | 
 |             ++__r; | 
 |     } | 
 |     return __r; | 
 | } | 
 |  | 
 | #endif  // _LIBCPP_HAS_NO_VARIADICS | 
 |  | 
 | template <class _L0, class _L1> | 
 | void | 
 | lock(_L0& __l0, _L1& __l1) | 
 | { | 
 |     while (true) | 
 |     { | 
 |         { | 
 |             unique_lock<_L0> __u0(__l0); | 
 |             if (__l1.try_lock()) | 
 |             { | 
 |                 __u0.release(); | 
 |                 break; | 
 |             } | 
 |         } | 
 |         sched_yield(); | 
 |         { | 
 |             unique_lock<_L1> __u1(__l1); | 
 |             if (__l0.try_lock()) | 
 |             { | 
 |                 __u1.release(); | 
 |                 break; | 
 |             } | 
 |         } | 
 |         sched_yield(); | 
 |     } | 
 | } | 
 |  | 
 | #ifndef _LIBCPP_HAS_NO_VARIADICS | 
 |  | 
 | template <class _L0, class _L1, class ..._L2> | 
 | void | 
 | __lock_first(int __i, _L0& __l0, _L1& __l1, _L2& ...__l2) | 
 | { | 
 |     while (true) | 
 |     { | 
 |         switch (__i) | 
 |         { | 
 |         case 0: | 
 |             { | 
 |                 unique_lock<_L0> __u0(__l0); | 
 |                 __i = try_lock(__l1, __l2...); | 
 |                 if (__i == -1) | 
 |                 { | 
 |                     __u0.release(); | 
 |                     return; | 
 |                 } | 
 |             } | 
 |             ++__i; | 
 |             sched_yield(); | 
 |             break; | 
 |         case 1: | 
 |             { | 
 |                 unique_lock<_L1> __u1(__l1); | 
 |                 __i = try_lock(__l2..., __l0); | 
 |                 if (__i == -1) | 
 |                 { | 
 |                     __u1.release(); | 
 |                     return; | 
 |                 } | 
 |             } | 
 |             if (__i == sizeof...(_L2)) | 
 |                 __i = 0; | 
 |             else | 
 |                 __i += 2; | 
 |             sched_yield(); | 
 |             break; | 
 |         default: | 
 |             __lock_first(__i - 2, __l2..., __l0, __l1); | 
 |             return; | 
 |         } | 
 |     } | 
 | } | 
 |  | 
 | template <class _L0, class _L1, class ..._L2> | 
 | inline | 
 | void | 
 | lock(_L0& __l0, _L1& __l1, _L2& ...__l2) | 
 | { | 
 |     __lock_first(0, __l0, __l1, __l2...); | 
 | } | 
 |  | 
 | #endif  // _LIBCPP_HAS_NO_VARIADICS | 
 |  | 
 | struct once_flag; | 
 |  | 
 | #ifndef _LIBCPP_HAS_NO_VARIADICS | 
 |  | 
 | template<class _Callable, class... _Args> | 
 |   void call_once(once_flag&, _Callable&&, _Args&&...); | 
 |  | 
 | #else  // _LIBCPP_HAS_NO_VARIADICS | 
 |  | 
 | template<class _Callable> | 
 |   void call_once(once_flag&, _Callable); | 
 |  | 
 | #endif  // _LIBCPP_HAS_NO_VARIADICS | 
 |  | 
 | struct once_flag | 
 | { | 
 |     // constexpr | 
 |         once_flag() {} | 
 |  | 
 | private: | 
 |     once_flag(const once_flag&); // = delete; | 
 |     once_flag& operator=(const once_flag&); // = delete; | 
 |  | 
 |     unsigned long __state_; | 
 |  | 
 | #ifndef _LIBCPP_HAS_NO_VARIADICS | 
 |     template<class _Callable, class... _Args> | 
 |     friend | 
 |     void call_once(once_flag&, _Callable&&, _Args&&...); | 
 | #else  // _LIBCPP_HAS_NO_VARIADICS | 
 |     template<class _Callable> | 
 |     friend | 
 |     void call_once(once_flag&, _Callable); | 
 | #endif  // _LIBCPP_HAS_NO_VARIADICS | 
 | }; | 
 |  | 
 | template <class _F> | 
 | class __call_once_param | 
 | { | 
 |     _F __f_; | 
 | public: | 
 | #ifdef _LIBCPP_MOVE | 
 |     explicit __call_once_param(_F&& __f) : __f_(_STD::move(__f)) {} | 
 | #else | 
 |     explicit __call_once_param(const _F& __f) : __f_(__f) {} | 
 | #endif | 
 |  | 
 |     void operator()() | 
 |     { | 
 |         __f_(); | 
 |     } | 
 | }; | 
 |  | 
 | template <class _F> | 
 | void | 
 | __call_once_proxy(void* __vp) | 
 | { | 
 |     __call_once_param<_F>* __p = static_cast<__call_once_param<_F>*>(__vp); | 
 |     (*__p)(); | 
 | } | 
 |  | 
 | void __call_once(volatile unsigned long&, void*, void(*)(void*)); | 
 |  | 
 | #ifndef _LIBCPP_HAS_NO_VARIADICS | 
 |  | 
 | template<class _Callable, class... _Args> | 
 | inline _LIBCPP_INLINE_VISIBILITY | 
 | void | 
 | call_once(once_flag& __flag, _Callable&& __func, _Args&&... __args) | 
 | { | 
 |     if (__builtin_expect(__flag.__state_ , ~0ul) != ~0ul) | 
 |     { | 
 |         typedef decltype(std::bind(std::forward<_Callable>(__func), | 
 |                          std::forward<_Args>(__args)...)) _G; | 
 |         __call_once_param<_G> __p(std::bind(std::forward<_Callable>(__func), | 
 |                                  std::forward<_Args>(__args)...)); | 
 |         __call_once(__flag.__state_, &__p, &__call_once_proxy<_G>); | 
 |     } | 
 | } | 
 |  | 
 | #else  // _LIBCPP_HAS_NO_VARIADICS | 
 |  | 
 | template<class _Callable> | 
 | inline _LIBCPP_INLINE_VISIBILITY | 
 | void | 
 | call_once(once_flag& __flag, _Callable __func) | 
 | { | 
 |     if (__flag.__state_ != ~0ul) | 
 |     { | 
 |         __call_once_param<_Callable> __p(__func); | 
 |         __call_once(__flag.__state_, &__p, &__call_once_proxy<_Callable>); | 
 |     } | 
 | } | 
 |  | 
 | #endif  // _LIBCPP_HAS_NO_VARIADICS | 
 |  | 
 | _LIBCPP_END_NAMESPACE_STD | 
 |  | 
 | #endif  // _LIBCPP_MUTEX |