brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.7 KiB · fdd7f1e Raw
376 lines · plain
1// -*- C++ -*-2//===----------------------------------------------------------------------===//3//4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.5// See https://llvm.org/LICENSE.txt for license information.6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception7//8//===----------------------------------------------------------------------===//9 10#ifndef _LIBCPP___CXX03_MUTEX11#define _LIBCPP___CXX03_MUTEX12 13/*14    mutex synopsis15 16namespace std17{18 19class mutex20{21public:22     constexpr mutex() noexcept;23     ~mutex();24 25    mutex(const mutex&) = delete;26    mutex& operator=(const mutex&) = delete;27 28    void lock();29    bool try_lock();30    void unlock();31 32    typedef pthread_mutex_t* native_handle_type;33    native_handle_type native_handle();34};35 36class recursive_mutex37{38public:39     recursive_mutex();40     ~recursive_mutex();41 42    recursive_mutex(const recursive_mutex&) = delete;43    recursive_mutex& operator=(const recursive_mutex&) = delete;44 45    void lock();46    bool try_lock() noexcept;47    void unlock();48 49    typedef pthread_mutex_t* native_handle_type;50    native_handle_type native_handle();51};52 53class timed_mutex54{55public:56     timed_mutex();57     ~timed_mutex();58 59    timed_mutex(const timed_mutex&) = delete;60    timed_mutex& operator=(const timed_mutex&) = delete;61 62    void lock();63    bool try_lock();64    template <class Rep, class Period>65        bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);66    template <class Clock, class Duration>67        bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);68    void unlock();69};70 71class recursive_timed_mutex72{73public:74     recursive_timed_mutex();75     ~recursive_timed_mutex();76 77    recursive_timed_mutex(const recursive_timed_mutex&) = delete;78    recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete;79 80    void lock();81    bool try_lock() noexcept;82    template <class Rep, class Period>83        bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);84    template <class Clock, class Duration>85        bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);86    void unlock();87};88 89struct defer_lock_t { explicit defer_lock_t() = default; };90struct try_to_lock_t { explicit try_to_lock_t() = default; };91struct adopt_lock_t { explicit adopt_lock_t() = default; };92 93inline constexpr defer_lock_t  defer_lock{};94inline constexpr try_to_lock_t try_to_lock{};95inline constexpr adopt_lock_t  adopt_lock{};96 97template <class Mutex>98class lock_guard99{100public:101    typedef Mutex mutex_type;102 103    explicit lock_guard(mutex_type& m);104    lock_guard(mutex_type& m, adopt_lock_t);105    ~lock_guard();106 107    lock_guard(lock_guard const&) = delete;108    lock_guard& operator=(lock_guard const&) = delete;109};110 111template <class... MutexTypes>112class scoped_lock // C++17113{114public:115    using mutex_type = Mutex;  // Only if sizeof...(MutexTypes) == 1116 117    explicit scoped_lock(MutexTypes&... m);118    scoped_lock(adopt_lock_t, MutexTypes&... m);119    ~scoped_lock();120    scoped_lock(scoped_lock const&) = delete;121    scoped_lock& operator=(scoped_lock const&) = delete;122private:123    tuple<MutexTypes&...> pm; // exposition only124};125 126template <class Mutex>127class unique_lock128{129public:130    typedef Mutex mutex_type;131    unique_lock() noexcept;132    explicit unique_lock(mutex_type& m);133    unique_lock(mutex_type& m, defer_lock_t) noexcept;134    unique_lock(mutex_type& m, try_to_lock_t);135    unique_lock(mutex_type& m, adopt_lock_t);136    template <class Clock, class Duration>137        unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);138    template <class Rep, class Period>139        unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);140    ~unique_lock();141 142    unique_lock(unique_lock const&) = delete;143    unique_lock& operator=(unique_lock const&) = delete;144 145    unique_lock(unique_lock&& u) noexcept;146    unique_lock& operator=(unique_lock&& u) noexcept;147 148    void lock();149    bool try_lock();150 151    template <class Rep, class Period>152        bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);153    template <class Clock, class Duration>154        bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);155 156    void unlock();157 158    void swap(unique_lock& u) noexcept;159    mutex_type* release() noexcept;160 161    bool owns_lock() const noexcept;162    explicit operator bool () const noexcept;163    mutex_type* mutex() const noexcept;164};165 166template <class Mutex>167  void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) noexcept;168 169template <class L1, class L2, class... L3>170  int try_lock(L1&, L2&, L3&...);171template <class L1, class L2, class... L3>172  void lock(L1&, L2&, L3&...);173 174struct once_flag175{176    constexpr once_flag() noexcept;177 178    once_flag(const once_flag&) = delete;179    once_flag& operator=(const once_flag&) = delete;180};181 182template<class Callable, class ...Args>183  void call_once(once_flag& flag, Callable&& func, Args&&... args);184 185}  // std186 187*/188 189#include <__cxx03/__chrono/steady_clock.h>190#include <__cxx03/__chrono/time_point.h>191#include <__cxx03/__condition_variable/condition_variable.h>192#include <__cxx03/__config>193#include <__cxx03/__memory/shared_ptr.h>194#include <__cxx03/__mutex/lock_guard.h>195#include <__cxx03/__mutex/mutex.h>196#include <__cxx03/__mutex/once_flag.h>197#include <__cxx03/__mutex/tag_types.h>198#include <__cxx03/__mutex/unique_lock.h>199#include <__cxx03/__thread/id.h>200#include <__cxx03/__thread/support.h>201#include <__cxx03/__utility/forward.h>202#include <__cxx03/cstddef>203#include <__cxx03/limits>204#include <__cxx03/version>205 206#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)207#  pragma GCC system_header208#endif209 210_LIBCPP_PUSH_MACROS211#include <__cxx03/__undef_macros>212 213_LIBCPP_BEGIN_NAMESPACE_STD214 215#ifndef _LIBCPP_HAS_NO_THREADS216 217class _LIBCPP_EXPORTED_FROM_ABI recursive_mutex {218  __libcpp_recursive_mutex_t __m_;219 220public:221  recursive_mutex();222  ~recursive_mutex();223 224  recursive_mutex(const recursive_mutex&)            = delete;225  recursive_mutex& operator=(const recursive_mutex&) = delete;226 227  void lock();228  bool try_lock() _NOEXCEPT;229  void unlock() _NOEXCEPT;230 231  typedef __libcpp_recursive_mutex_t* native_handle_type;232 233  _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return &__m_; }234};235 236class _LIBCPP_EXPORTED_FROM_ABI timed_mutex {237  mutex __m_;238  condition_variable __cv_;239  bool __locked_;240 241public:242  timed_mutex();243  ~timed_mutex();244 245  timed_mutex(const timed_mutex&)            = delete;246  timed_mutex& operator=(const timed_mutex&) = delete;247 248public:249  void lock();250  bool try_lock() _NOEXCEPT;251  template <class _Rep, class _Period>252  _LIBCPP_HIDE_FROM_ABI bool try_lock_for(const chrono::duration<_Rep, _Period>& __d) {253    return try_lock_until(chrono::steady_clock::now() + __d);254  }255  template <class _Clock, class _Duration>256  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS bool257  try_lock_until(const chrono::time_point<_Clock, _Duration>& __t);258  void unlock() _NOEXCEPT;259};260 261template <class _Clock, class _Duration>262bool timed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) {263  using namespace chrono;264  unique_lock<mutex> __lk(__m_);265  bool __no_timeout = _Clock::now() < __t;266  while (__no_timeout && __locked_)267    __no_timeout = __cv_.wait_until(__lk, __t) == cv_status::no_timeout;268  if (!__locked_) {269    __locked_ = true;270    return true;271  }272  return false;273}274 275class _LIBCPP_EXPORTED_FROM_ABI recursive_timed_mutex {276  mutex __m_;277  condition_variable __cv_;278  size_t __count_;279  __thread_id __id_;280 281public:282  recursive_timed_mutex();283  ~recursive_timed_mutex();284 285  recursive_timed_mutex(const recursive_timed_mutex&)            = delete;286  recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete;287 288  void lock();289  bool try_lock() _NOEXCEPT;290  template <class _Rep, class _Period>291  _LIBCPP_HIDE_FROM_ABI bool try_lock_for(const chrono::duration<_Rep, _Period>& __d) {292    return try_lock_until(chrono::steady_clock::now() + __d);293  }294  template <class _Clock, class _Duration>295  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS bool296  try_lock_until(const chrono::time_point<_Clock, _Duration>& __t);297  void unlock() _NOEXCEPT;298};299 300template <class _Clock, class _Duration>301bool recursive_timed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) {302  using namespace chrono;303  __thread_id __id = this_thread::get_id();304  unique_lock<mutex> __lk(__m_);305  if (__id == __id_) {306    if (__count_ == numeric_limits<size_t>::max())307      return false;308    ++__count_;309    return true;310  }311  bool __no_timeout = _Clock::now() < __t;312  while (__no_timeout && __count_ != 0)313    __no_timeout = __cv_.wait_until(__lk, __t) == cv_status::no_timeout;314  if (__count_ == 0) {315    __count_ = 1;316    __id_    = __id;317    return true;318  }319  return false;320}321 322template <class _L0, class _L1>323_LIBCPP_HIDE_FROM_ABI int try_lock(_L0& __l0, _L1& __l1) {324  unique_lock<_L0> __u0(__l0, try_to_lock_t());325  if (__u0.owns_lock()) {326    if (__l1.try_lock()) {327      __u0.release();328      return -1;329    } else330      return 1;331  }332  return 0;333}334 335template <class _L0, class _L1>336_LIBCPP_HIDE_FROM_ABI void lock(_L0& __l0, _L1& __l1) {337  while (true) {338    {339      unique_lock<_L0> __u0(__l0);340      if (__l1.try_lock()) {341        __u0.release();342        break;343      }344    }345    __libcpp_thread_yield();346    {347      unique_lock<_L1> __u1(__l1);348      if (__l0.try_lock()) {349        __u1.release();350        break;351      }352    }353    __libcpp_thread_yield();354  }355}356#endif   // !_LIBCPP_HAS_NO_THREADS357 358_LIBCPP_END_NAMESPACE_STD359 360_LIBCPP_POP_MACROS361 362#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES)363#  include <__cxx03/atomic>364#  include <__cxx03/cstdlib>365#  include <__cxx03/cstring>366#  include <__cxx03/ctime>367#  include <__cxx03/iosfwd>368#  include <__cxx03/new>369#  include <__cxx03/stdexcept>370#  include <__cxx03/system_error>371#  include <__cxx03/type_traits>372#  include <__cxx03/typeinfo>373#endif374 375#endif // _LIBCPP___CXX03_MUTEX376