Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/c++/v1/__cxx03/mutex is written in an unsupported language. File is not indexed.

0001 // -*- C++ -*-
0002 //===----------------------------------------------------------------------===//
0003 //
0004 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0005 // See https://llvm.org/LICENSE.txt for license information.
0006 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0007 //
0008 //===----------------------------------------------------------------------===//
0009 
0010 #ifndef _LIBCPP___CXX03_MUTEX
0011 #define _LIBCPP___CXX03_MUTEX
0012 
0013 /*
0014     mutex synopsis
0015 
0016 namespace std
0017 {
0018 
0019 class mutex
0020 {
0021 public:
0022      constexpr mutex() noexcept;
0023      ~mutex();
0024 
0025     mutex(const mutex&) = delete;
0026     mutex& operator=(const mutex&) = delete;
0027 
0028     void lock();
0029     bool try_lock();
0030     void unlock();
0031 
0032     typedef pthread_mutex_t* native_handle_type;
0033     native_handle_type native_handle();
0034 };
0035 
0036 class recursive_mutex
0037 {
0038 public:
0039      recursive_mutex();
0040      ~recursive_mutex();
0041 
0042     recursive_mutex(const recursive_mutex&) = delete;
0043     recursive_mutex& operator=(const recursive_mutex&) = delete;
0044 
0045     void lock();
0046     bool try_lock() noexcept;
0047     void unlock();
0048 
0049     typedef pthread_mutex_t* native_handle_type;
0050     native_handle_type native_handle();
0051 };
0052 
0053 class timed_mutex
0054 {
0055 public:
0056      timed_mutex();
0057      ~timed_mutex();
0058 
0059     timed_mutex(const timed_mutex&) = delete;
0060     timed_mutex& operator=(const timed_mutex&) = delete;
0061 
0062     void lock();
0063     bool try_lock();
0064     template <class Rep, class Period>
0065         bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
0066     template <class Clock, class Duration>
0067         bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
0068     void unlock();
0069 };
0070 
0071 class recursive_timed_mutex
0072 {
0073 public:
0074      recursive_timed_mutex();
0075      ~recursive_timed_mutex();
0076 
0077     recursive_timed_mutex(const recursive_timed_mutex&) = delete;
0078     recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete;
0079 
0080     void lock();
0081     bool try_lock() noexcept;
0082     template <class Rep, class Period>
0083         bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
0084     template <class Clock, class Duration>
0085         bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
0086     void unlock();
0087 };
0088 
0089 struct defer_lock_t { explicit defer_lock_t() = default; };
0090 struct try_to_lock_t { explicit try_to_lock_t() = default; };
0091 struct adopt_lock_t { explicit adopt_lock_t() = default; };
0092 
0093 inline constexpr defer_lock_t  defer_lock{};
0094 inline constexpr try_to_lock_t try_to_lock{};
0095 inline constexpr adopt_lock_t  adopt_lock{};
0096 
0097 template <class Mutex>
0098 class lock_guard
0099 {
0100 public:
0101     typedef Mutex mutex_type;
0102 
0103     explicit lock_guard(mutex_type& m);
0104     lock_guard(mutex_type& m, adopt_lock_t);
0105     ~lock_guard();
0106 
0107     lock_guard(lock_guard const&) = delete;
0108     lock_guard& operator=(lock_guard const&) = delete;
0109 };
0110 
0111 template <class... MutexTypes>
0112 class scoped_lock // C++17
0113 {
0114 public:
0115     using mutex_type = Mutex;  // Only if sizeof...(MutexTypes) == 1
0116 
0117     explicit scoped_lock(MutexTypes&... m);
0118     scoped_lock(adopt_lock_t, MutexTypes&... m);
0119     ~scoped_lock();
0120     scoped_lock(scoped_lock const&) = delete;
0121     scoped_lock& operator=(scoped_lock const&) = delete;
0122 private:
0123     tuple<MutexTypes&...> pm; // exposition only
0124 };
0125 
0126 template <class Mutex>
0127 class unique_lock
0128 {
0129 public:
0130     typedef Mutex mutex_type;
0131     unique_lock() noexcept;
0132     explicit unique_lock(mutex_type& m);
0133     unique_lock(mutex_type& m, defer_lock_t) noexcept;
0134     unique_lock(mutex_type& m, try_to_lock_t);
0135     unique_lock(mutex_type& m, adopt_lock_t);
0136     template <class Clock, class Duration>
0137         unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
0138     template <class Rep, class Period>
0139         unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
0140     ~unique_lock();
0141 
0142     unique_lock(unique_lock const&) = delete;
0143     unique_lock& operator=(unique_lock const&) = delete;
0144 
0145     unique_lock(unique_lock&& u) noexcept;
0146     unique_lock& operator=(unique_lock&& u) noexcept;
0147 
0148     void lock();
0149     bool try_lock();
0150 
0151     template <class Rep, class Period>
0152         bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
0153     template <class Clock, class Duration>
0154         bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
0155 
0156     void unlock();
0157 
0158     void swap(unique_lock& u) noexcept;
0159     mutex_type* release() noexcept;
0160 
0161     bool owns_lock() const noexcept;
0162     explicit operator bool () const noexcept;
0163     mutex_type* mutex() const noexcept;
0164 };
0165 
0166 template <class Mutex>
0167   void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) noexcept;
0168 
0169 template <class L1, class L2, class... L3>
0170   int try_lock(L1&, L2&, L3&...);
0171 template <class L1, class L2, class... L3>
0172   void lock(L1&, L2&, L3&...);
0173 
0174 struct once_flag
0175 {
0176     constexpr once_flag() noexcept;
0177 
0178     once_flag(const once_flag&) = delete;
0179     once_flag& operator=(const once_flag&) = delete;
0180 };
0181 
0182 template<class Callable, class ...Args>
0183   void call_once(once_flag& flag, Callable&& func, Args&&... args);
0184 
0185 }  // std
0186 
0187 */
0188 
0189 #include <__cxx03/__chrono/steady_clock.h>
0190 #include <__cxx03/__chrono/time_point.h>
0191 #include <__cxx03/__condition_variable/condition_variable.h>
0192 #include <__cxx03/__config>
0193 #include <__cxx03/__memory/shared_ptr.h>
0194 #include <__cxx03/__mutex/lock_guard.h>
0195 #include <__cxx03/__mutex/mutex.h>
0196 #include <__cxx03/__mutex/once_flag.h>
0197 #include <__cxx03/__mutex/tag_types.h>
0198 #include <__cxx03/__mutex/unique_lock.h>
0199 #include <__cxx03/__thread/id.h>
0200 #include <__cxx03/__thread/support.h>
0201 #include <__cxx03/__utility/forward.h>
0202 #include <__cxx03/cstddef>
0203 #include <__cxx03/limits>
0204 #ifndef _LIBCPP_CXX03_LANG
0205 #  include <__cxx03/tuple>
0206 #endif
0207 #include <__cxx03/version>
0208 
0209 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0210 #  pragma GCC system_header
0211 #endif
0212 
0213 _LIBCPP_PUSH_MACROS
0214 #include <__cxx03/__undef_macros>
0215 
0216 _LIBCPP_BEGIN_NAMESPACE_STD
0217 
0218 #ifndef _LIBCPP_HAS_NO_THREADS
0219 
0220 class _LIBCPP_EXPORTED_FROM_ABI recursive_mutex {
0221   __libcpp_recursive_mutex_t __m_;
0222 
0223 public:
0224   recursive_mutex();
0225   ~recursive_mutex();
0226 
0227   recursive_mutex(const recursive_mutex&)            = delete;
0228   recursive_mutex& operator=(const recursive_mutex&) = delete;
0229 
0230   void lock();
0231   bool try_lock() _NOEXCEPT;
0232   void unlock() _NOEXCEPT;
0233 
0234   typedef __libcpp_recursive_mutex_t* native_handle_type;
0235 
0236   _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return &__m_; }
0237 };
0238 
0239 class _LIBCPP_EXPORTED_FROM_ABI timed_mutex {
0240   mutex __m_;
0241   condition_variable __cv_;
0242   bool __locked_;
0243 
0244 public:
0245   timed_mutex();
0246   ~timed_mutex();
0247 
0248   timed_mutex(const timed_mutex&)            = delete;
0249   timed_mutex& operator=(const timed_mutex&) = delete;
0250 
0251 public:
0252   void lock();
0253   bool try_lock() _NOEXCEPT;
0254   template <class _Rep, class _Period>
0255   _LIBCPP_HIDE_FROM_ABI bool try_lock_for(const chrono::duration<_Rep, _Period>& __d) {
0256     return try_lock_until(chrono::steady_clock::now() + __d);
0257   }
0258   template <class _Clock, class _Duration>
0259   _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS bool
0260   try_lock_until(const chrono::time_point<_Clock, _Duration>& __t);
0261   void unlock() _NOEXCEPT;
0262 };
0263 
0264 template <class _Clock, class _Duration>
0265 bool timed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) {
0266   using namespace chrono;
0267   unique_lock<mutex> __lk(__m_);
0268   bool __no_timeout = _Clock::now() < __t;
0269   while (__no_timeout && __locked_)
0270     __no_timeout = __cv_.wait_until(__lk, __t) == cv_status::no_timeout;
0271   if (!__locked_) {
0272     __locked_ = true;
0273     return true;
0274   }
0275   return false;
0276 }
0277 
0278 class _LIBCPP_EXPORTED_FROM_ABI recursive_timed_mutex {
0279   mutex __m_;
0280   condition_variable __cv_;
0281   size_t __count_;
0282   __thread_id __id_;
0283 
0284 public:
0285   recursive_timed_mutex();
0286   ~recursive_timed_mutex();
0287 
0288   recursive_timed_mutex(const recursive_timed_mutex&)            = delete;
0289   recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete;
0290 
0291   void lock();
0292   bool try_lock() _NOEXCEPT;
0293   template <class _Rep, class _Period>
0294   _LIBCPP_HIDE_FROM_ABI bool try_lock_for(const chrono::duration<_Rep, _Period>& __d) {
0295     return try_lock_until(chrono::steady_clock::now() + __d);
0296   }
0297   template <class _Clock, class _Duration>
0298   _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS bool
0299   try_lock_until(const chrono::time_point<_Clock, _Duration>& __t);
0300   void unlock() _NOEXCEPT;
0301 };
0302 
0303 template <class _Clock, class _Duration>
0304 bool recursive_timed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) {
0305   using namespace chrono;
0306   __thread_id __id = this_thread::get_id();
0307   unique_lock<mutex> __lk(__m_);
0308   if (__id == __id_) {
0309     if (__count_ == numeric_limits<size_t>::max())
0310       return false;
0311     ++__count_;
0312     return true;
0313   }
0314   bool __no_timeout = _Clock::now() < __t;
0315   while (__no_timeout && __count_ != 0)
0316     __no_timeout = __cv_.wait_until(__lk, __t) == cv_status::no_timeout;
0317   if (__count_ == 0) {
0318     __count_ = 1;
0319     __id_    = __id;
0320     return true;
0321   }
0322   return false;
0323 }
0324 
0325 template <class _L0, class _L1>
0326 _LIBCPP_HIDE_FROM_ABI int try_lock(_L0& __l0, _L1& __l1) {
0327   unique_lock<_L0> __u0(__l0, try_to_lock_t());
0328   if (__u0.owns_lock()) {
0329     if (__l1.try_lock()) {
0330       __u0.release();
0331       return -1;
0332     } else
0333       return 1;
0334   }
0335   return 0;
0336 }
0337 
0338 #  ifndef _LIBCPP_CXX03_LANG
0339 
0340 template <class _L0, class _L1, class _L2, class... _L3>
0341 _LIBCPP_HIDE_FROM_ABI int try_lock(_L0& __l0, _L1& __l1, _L2& __l2, _L3&... __l3) {
0342   int __r = 0;
0343   unique_lock<_L0> __u0(__l0, try_to_lock);
0344   if (__u0.owns_lock()) {
0345     __r = std::try_lock(__l1, __l2, __l3...);
0346     if (__r == -1)
0347       __u0.release();
0348     else
0349       ++__r;
0350   }
0351   return __r;
0352 }
0353 
0354 #  endif // _LIBCPP_CXX03_LANG
0355 
0356 template <class _L0, class _L1>
0357 _LIBCPP_HIDE_FROM_ABI void lock(_L0& __l0, _L1& __l1) {
0358   while (true) {
0359     {
0360       unique_lock<_L0> __u0(__l0);
0361       if (__l1.try_lock()) {
0362         __u0.release();
0363         break;
0364       }
0365     }
0366     __libcpp_thread_yield();
0367     {
0368       unique_lock<_L1> __u1(__l1);
0369       if (__l0.try_lock()) {
0370         __u1.release();
0371         break;
0372       }
0373     }
0374     __libcpp_thread_yield();
0375   }
0376 }
0377 
0378 #  ifndef _LIBCPP_CXX03_LANG
0379 
0380 template <class _L0, class _L1, class _L2, class... _L3>
0381 void __lock_first(int __i, _L0& __l0, _L1& __l1, _L2& __l2, _L3&... __l3) {
0382   while (true) {
0383     switch (__i) {
0384     case 0: {
0385       unique_lock<_L0> __u0(__l0);
0386       __i = std::try_lock(__l1, __l2, __l3...);
0387       if (__i == -1) {
0388         __u0.release();
0389         return;
0390       }
0391     }
0392       ++__i;
0393       __libcpp_thread_yield();
0394       break;
0395     case 1: {
0396       unique_lock<_L1> __u1(__l1);
0397       __i = std::try_lock(__l2, __l3..., __l0);
0398       if (__i == -1) {
0399         __u1.release();
0400         return;
0401       }
0402     }
0403       if (__i == sizeof...(_L3) + 1)
0404         __i = 0;
0405       else
0406         __i += 2;
0407       __libcpp_thread_yield();
0408       break;
0409     default:
0410       std::__lock_first(__i - 2, __l2, __l3..., __l0, __l1);
0411       return;
0412     }
0413   }
0414 }
0415 
0416 template <class _L0, class _L1, class _L2, class... _L3>
0417 inline _LIBCPP_HIDE_FROM_ABI void lock(_L0& __l0, _L1& __l1, _L2& __l2, _L3&... __l3) {
0418   std::__lock_first(0, __l0, __l1, __l2, __l3...);
0419 }
0420 
0421 #  endif // _LIBCPP_CXX03_LANG
0422 
0423 #  if _LIBCPP_STD_VER >= 17
0424 template <class... _Mutexes>
0425 class _LIBCPP_TEMPLATE_VIS scoped_lock;
0426 
0427 template <>
0428 class _LIBCPP_TEMPLATE_VIS scoped_lock<> {
0429 public:
0430   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI explicit scoped_lock() {}
0431   ~scoped_lock() = default;
0432 
0433   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI explicit scoped_lock(adopt_lock_t) {}
0434 
0435   scoped_lock(scoped_lock const&)            = delete;
0436   scoped_lock& operator=(scoped_lock const&) = delete;
0437 };
0438 
0439 template <class _Mutex>
0440 class _LIBCPP_TEMPLATE_VIS _LIBCPP_THREAD_SAFETY_ANNOTATION(scoped_lockable) scoped_lock<_Mutex> {
0441 public:
0442   typedef _Mutex mutex_type;
0443 
0444 private:
0445   mutex_type& __m_;
0446 
0447 public:
0448   [[nodiscard]]
0449   _LIBCPP_HIDE_FROM_ABI explicit scoped_lock(mutex_type& __m) _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability(__m))
0450       : __m_(__m) {
0451     __m_.lock();
0452   }
0453 
0454   ~scoped_lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability()) { __m_.unlock(); }
0455 
0456   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI explicit scoped_lock(adopt_lock_t, mutex_type& __m)
0457       _LIBCPP_THREAD_SAFETY_ANNOTATION(requires_capability(__m))
0458       : __m_(__m) {}
0459 
0460   scoped_lock(scoped_lock const&)            = delete;
0461   scoped_lock& operator=(scoped_lock const&) = delete;
0462 };
0463 
0464 template <class... _MArgs>
0465 class _LIBCPP_TEMPLATE_VIS scoped_lock {
0466   static_assert(sizeof...(_MArgs) > 1, "At least 2 lock types required");
0467   typedef tuple<_MArgs&...> _MutexTuple;
0468 
0469 public:
0470   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI explicit scoped_lock(_MArgs&... __margs) : __t_(__margs...) {
0471     std::lock(__margs...);
0472   }
0473 
0474   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI scoped_lock(adopt_lock_t, _MArgs&... __margs) : __t_(__margs...) {}
0475 
0476   _LIBCPP_HIDE_FROM_ABI ~scoped_lock() {
0477     typedef typename __make_tuple_indices<sizeof...(_MArgs)>::type _Indices;
0478     __unlock_unpack(_Indices{}, __t_);
0479   }
0480 
0481   scoped_lock(scoped_lock const&)            = delete;
0482   scoped_lock& operator=(scoped_lock const&) = delete;
0483 
0484 private:
0485   template <size_t... _Indx>
0486   _LIBCPP_HIDE_FROM_ABI static void __unlock_unpack(__tuple_indices<_Indx...>, _MutexTuple& __mt) {
0487     (std::get<_Indx>(__mt).unlock(), ...);
0488   }
0489 
0490   _MutexTuple __t_;
0491 };
0492 _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(scoped_lock);
0493 
0494 #  endif // _LIBCPP_STD_VER >= 17
0495 #endif   // !_LIBCPP_HAS_NO_THREADS
0496 
0497 _LIBCPP_END_NAMESPACE_STD
0498 
0499 _LIBCPP_POP_MACROS
0500 
0501 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
0502 #  include <__cxx03/atomic>
0503 #  include <__cxx03/concepts>
0504 #  include <__cxx03/cstdlib>
0505 #  include <__cxx03/cstring>
0506 #  include <__cxx03/ctime>
0507 #  include <__cxx03/initializer_list>
0508 #  include <__cxx03/iosfwd>
0509 #  include <__cxx03/new>
0510 #  include <__cxx03/stdexcept>
0511 #  include <__cxx03/system_error>
0512 #  include <__cxx03/type_traits>
0513 #  include <__cxx03/typeinfo>
0514 #endif
0515 
0516 #endif // _LIBCPP___CXX03_MUTEX