__mutex_base 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. // -*- C++ -*-
  2. //===----------------------------------------------------------------------===//
  3. //
  4. // The LLVM Compiler Infrastructure
  5. //
  6. // This file is dual licensed under the MIT and the University of Illinois Open
  7. // Source Licenses. See LICENSE.TXT for details.
  8. //
  9. //===----------------------------------------------------------------------===//
  10. #ifndef _LIBCPP___MUTEX_BASE
  11. #define _LIBCPP___MUTEX_BASE
  12. #include <__config>
  13. #include <chrono>
  14. #include <system_error>
  15. #include <__threading_support>
  16. #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
  17. #pragma GCC system_header
  18. #endif
  19. _LIBCPP_BEGIN_NAMESPACE_STD
  20. #ifndef _LIBCPP_HAS_NO_THREADS
  21. #ifndef _LIBCPP_THREAD_SAFETY_ANNOTATION
  22. # ifdef _LIBCPP_HAS_THREAD_SAFETY_ANNOTATIONS
  23. # define _LIBCPP_THREAD_SAFETY_ANNOTATION(x) __attribute__((x))
  24. # else
  25. # define _LIBCPP_THREAD_SAFETY_ANNOTATION(x)
  26. # endif
  27. #endif // _LIBCPP_THREAD_SAFETY_ANNOTATION
  28. class _LIBCPP_TYPE_VIS _LIBCPP_THREAD_SAFETY_ANNOTATION(capability("mutex")) mutex
  29. {
  30. #ifndef _LIBCPP_HAS_NO_CONSTEXPR
  31. __libcpp_mutex_t __m_ = _LIBCPP_MUTEX_INITIALIZER;
  32. #else
  33. __libcpp_mutex_t __m_;
  34. #endif
  35. public:
  36. _LIBCPP_INLINE_VISIBILITY
  37. #ifndef _LIBCPP_HAS_NO_CONSTEXPR
  38. constexpr mutex() _NOEXCEPT _LIBCPP_DEFAULT
  39. #else
  40. mutex() _NOEXCEPT {__m_ = (__libcpp_mutex_t)_LIBCPP_MUTEX_INITIALIZER;}
  41. #endif
  42. ~mutex();
  43. private:
  44. mutex(const mutex&);// = delete;
  45. mutex& operator=(const mutex&);// = delete;
  46. public:
  47. void lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability());
  48. bool try_lock() _NOEXCEPT _LIBCPP_THREAD_SAFETY_ANNOTATION(try_acquire_capability(true));
  49. void unlock() _NOEXCEPT _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability());
  50. typedef __libcpp_mutex_t* native_handle_type;
  51. _LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() {return &__m_;}
  52. };
  53. struct _LIBCPP_TYPE_VIS defer_lock_t {};
  54. struct _LIBCPP_TYPE_VIS try_to_lock_t {};
  55. struct _LIBCPP_TYPE_VIS adopt_lock_t {};
  56. #if defined(_LIBCPP_HAS_NO_CONSTEXPR) || defined(_LIBCPP_BUILDING_MUTEX)
  57. extern const defer_lock_t defer_lock;
  58. extern const try_to_lock_t try_to_lock;
  59. extern const adopt_lock_t adopt_lock;
  60. #else
  61. constexpr defer_lock_t defer_lock = defer_lock_t();
  62. constexpr try_to_lock_t try_to_lock = try_to_lock_t();
  63. constexpr adopt_lock_t adopt_lock = adopt_lock_t();
  64. #endif
  65. // Forward declare lock_guard as a variadic template even in C++03 to keep
  66. // the mangling consistent between dialects.
  67. #if defined(_LIBCPP_ABI_VARIADIC_LOCK_GUARD)
  68. template <class ..._Mutexes>
  69. class _LIBCPP_TYPE_VIS_ONLY lock_guard;
  70. #endif
  71. template <class _Mutex>
  72. class _LIBCPP_TYPE_VIS_ONLY _LIBCPP_THREAD_SAFETY_ANNOTATION(scoped_lockable)
  73. #if !defined(_LIBCPP_ABI_VARIADIC_LOCK_GUARD)
  74. lock_guard
  75. #else
  76. lock_guard<_Mutex>
  77. #endif
  78. {
  79. public:
  80. typedef _Mutex mutex_type;
  81. private:
  82. mutex_type& __m_;
  83. public:
  84. _LIBCPP_INLINE_VISIBILITY
  85. explicit lock_guard(mutex_type& __m) _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability(__m))
  86. : __m_(__m) {__m_.lock();}
  87. _LIBCPP_INLINE_VISIBILITY
  88. lock_guard(mutex_type& __m, adopt_lock_t) _LIBCPP_THREAD_SAFETY_ANNOTATION(requires_capability(__m))
  89. : __m_(__m) {}
  90. _LIBCPP_INLINE_VISIBILITY
  91. ~lock_guard() _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability()) {__m_.unlock();}
  92. private:
  93. lock_guard(lock_guard const&) _LIBCPP_EQUAL_DELETE;
  94. lock_guard& operator=(lock_guard const&) _LIBCPP_EQUAL_DELETE;
  95. };
  96. template <class _Mutex>
  97. class _LIBCPP_TYPE_VIS_ONLY unique_lock
  98. {
  99. public:
  100. typedef _Mutex mutex_type;
  101. private:
  102. mutex_type* __m_;
  103. bool __owns_;
  104. public:
  105. _LIBCPP_INLINE_VISIBILITY
  106. unique_lock() _NOEXCEPT : __m_(nullptr), __owns_(false) {}
  107. _LIBCPP_INLINE_VISIBILITY
  108. explicit unique_lock(mutex_type& __m)
  109. : __m_(_VSTD::addressof(__m)), __owns_(true) {__m_->lock();}
  110. _LIBCPP_INLINE_VISIBILITY
  111. unique_lock(mutex_type& __m, defer_lock_t) _NOEXCEPT
  112. : __m_(_VSTD::addressof(__m)), __owns_(false) {}
  113. _LIBCPP_INLINE_VISIBILITY
  114. unique_lock(mutex_type& __m, try_to_lock_t)
  115. : __m_(_VSTD::addressof(__m)), __owns_(__m.try_lock()) {}
  116. _LIBCPP_INLINE_VISIBILITY
  117. unique_lock(mutex_type& __m, adopt_lock_t)
  118. : __m_(_VSTD::addressof(__m)), __owns_(true) {}
  119. template <class _Clock, class _Duration>
  120. _LIBCPP_INLINE_VISIBILITY
  121. unique_lock(mutex_type& __m, const chrono::time_point<_Clock, _Duration>& __t)
  122. : __m_(_VSTD::addressof(__m)), __owns_(__m.try_lock_until(__t)) {}
  123. template <class _Rep, class _Period>
  124. _LIBCPP_INLINE_VISIBILITY
  125. unique_lock(mutex_type& __m, const chrono::duration<_Rep, _Period>& __d)
  126. : __m_(_VSTD::addressof(__m)), __owns_(__m.try_lock_for(__d)) {}
  127. _LIBCPP_INLINE_VISIBILITY
  128. ~unique_lock()
  129. {
  130. if (__owns_)
  131. __m_->unlock();
  132. }
  133. private:
  134. unique_lock(unique_lock const&); // = delete;
  135. unique_lock& operator=(unique_lock const&); // = delete;
  136. public:
  137. #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
  138. _LIBCPP_INLINE_VISIBILITY
  139. unique_lock(unique_lock&& __u) _NOEXCEPT
  140. : __m_(__u.__m_), __owns_(__u.__owns_)
  141. {__u.__m_ = nullptr; __u.__owns_ = false;}
  142. _LIBCPP_INLINE_VISIBILITY
  143. unique_lock& operator=(unique_lock&& __u) _NOEXCEPT
  144. {
  145. if (__owns_)
  146. __m_->unlock();
  147. __m_ = __u.__m_;
  148. __owns_ = __u.__owns_;
  149. __u.__m_ = nullptr;
  150. __u.__owns_ = false;
  151. return *this;
  152. }
  153. #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
  154. void lock();
  155. bool try_lock();
  156. template <class _Rep, class _Period>
  157. bool try_lock_for(const chrono::duration<_Rep, _Period>& __d);
  158. template <class _Clock, class _Duration>
  159. bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t);
  160. void unlock();
  161. _LIBCPP_INLINE_VISIBILITY
  162. void swap(unique_lock& __u) _NOEXCEPT
  163. {
  164. _VSTD::swap(__m_, __u.__m_);
  165. _VSTD::swap(__owns_, __u.__owns_);
  166. }
  167. _LIBCPP_INLINE_VISIBILITY
  168. mutex_type* release() _NOEXCEPT
  169. {
  170. mutex_type* __m = __m_;
  171. __m_ = nullptr;
  172. __owns_ = false;
  173. return __m;
  174. }
  175. _LIBCPP_INLINE_VISIBILITY
  176. bool owns_lock() const _NOEXCEPT {return __owns_;}
  177. _LIBCPP_INLINE_VISIBILITY
  178. _LIBCPP_EXPLICIT
  179. operator bool () const _NOEXCEPT {return __owns_;}
  180. _LIBCPP_INLINE_VISIBILITY
  181. mutex_type* mutex() const _NOEXCEPT {return __m_;}
  182. };
  183. template <class _Mutex>
  184. void
  185. unique_lock<_Mutex>::lock()
  186. {
  187. if (__m_ == nullptr)
  188. __throw_system_error(EPERM, "unique_lock::lock: references null mutex");
  189. if (__owns_)
  190. __throw_system_error(EDEADLK, "unique_lock::lock: already locked");
  191. __m_->lock();
  192. __owns_ = true;
  193. }
  194. template <class _Mutex>
  195. bool
  196. unique_lock<_Mutex>::try_lock()
  197. {
  198. if (__m_ == nullptr)
  199. __throw_system_error(EPERM, "unique_lock::try_lock: references null mutex");
  200. if (__owns_)
  201. __throw_system_error(EDEADLK, "unique_lock::try_lock: already locked");
  202. __owns_ = __m_->try_lock();
  203. return __owns_;
  204. }
  205. template <class _Mutex>
  206. template <class _Rep, class _Period>
  207. bool
  208. unique_lock<_Mutex>::try_lock_for(const chrono::duration<_Rep, _Period>& __d)
  209. {
  210. if (__m_ == nullptr)
  211. __throw_system_error(EPERM, "unique_lock::try_lock_for: references null mutex");
  212. if (__owns_)
  213. __throw_system_error(EDEADLK, "unique_lock::try_lock_for: already locked");
  214. __owns_ = __m_->try_lock_for(__d);
  215. return __owns_;
  216. }
  217. template <class _Mutex>
  218. template <class _Clock, class _Duration>
  219. bool
  220. unique_lock<_Mutex>::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t)
  221. {
  222. if (__m_ == nullptr)
  223. __throw_system_error(EPERM, "unique_lock::try_lock_until: references null mutex");
  224. if (__owns_)
  225. __throw_system_error(EDEADLK, "unique_lock::try_lock_until: already locked");
  226. __owns_ = __m_->try_lock_until(__t);
  227. return __owns_;
  228. }
  229. template <class _Mutex>
  230. void
  231. unique_lock<_Mutex>::unlock()
  232. {
  233. if (!__owns_)
  234. __throw_system_error(EPERM, "unique_lock::unlock: not locked");
  235. __m_->unlock();
  236. __owns_ = false;
  237. }
  238. template <class _Mutex>
  239. inline _LIBCPP_INLINE_VISIBILITY
  240. void
  241. swap(unique_lock<_Mutex>& __x, unique_lock<_Mutex>& __y) _NOEXCEPT
  242. {__x.swap(__y);}
  243. //enum class cv_status
  244. _LIBCPP_DECLARE_STRONG_ENUM(cv_status)
  245. {
  246. no_timeout,
  247. timeout
  248. };
  249. _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(cv_status)
  250. class _LIBCPP_TYPE_VIS condition_variable
  251. {
  252. #ifndef _LIBCPP_HAS_NO_CONSTEXPR
  253. __libcpp_condvar_t __cv_ = _LIBCPP_CONDVAR_INITIALIZER;
  254. #else
  255. __libcpp_condvar_t __cv_;
  256. #endif
  257. public:
  258. _LIBCPP_INLINE_VISIBILITY
  259. #ifndef _LIBCPP_HAS_NO_CONSTEXPR
  260. constexpr condition_variable() _NOEXCEPT _LIBCPP_DEFAULT
  261. #else
  262. condition_variable() _NOEXCEPT {__cv_ = (__libcpp_condvar_t)_LIBCPP_CONDVAR_INITIALIZER;}
  263. #endif
  264. ~condition_variable();
  265. private:
  266. condition_variable(const condition_variable&); // = delete;
  267. condition_variable& operator=(const condition_variable&); // = delete;
  268. public:
  269. void notify_one() _NOEXCEPT;
  270. void notify_all() _NOEXCEPT;
  271. void wait(unique_lock<mutex>& __lk) _NOEXCEPT;
  272. template <class _Predicate>
  273. void wait(unique_lock<mutex>& __lk, _Predicate __pred);
  274. template <class _Clock, class _Duration>
  275. cv_status
  276. wait_until(unique_lock<mutex>& __lk,
  277. const chrono::time_point<_Clock, _Duration>& __t);
  278. template <class _Clock, class _Duration, class _Predicate>
  279. bool
  280. wait_until(unique_lock<mutex>& __lk,
  281. const chrono::time_point<_Clock, _Duration>& __t,
  282. _Predicate __pred);
  283. template <class _Rep, class _Period>
  284. cv_status
  285. wait_for(unique_lock<mutex>& __lk,
  286. const chrono::duration<_Rep, _Period>& __d);
  287. template <class _Rep, class _Period, class _Predicate>
  288. bool
  289. _LIBCPP_INLINE_VISIBILITY
  290. wait_for(unique_lock<mutex>& __lk,
  291. const chrono::duration<_Rep, _Period>& __d,
  292. _Predicate __pred);
  293. typedef __libcpp_condvar_t* native_handle_type;
  294. _LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() {return &__cv_;}
  295. private:
  296. void __do_timed_wait(unique_lock<mutex>& __lk,
  297. chrono::time_point<chrono::system_clock, chrono::nanoseconds>) _NOEXCEPT;
  298. };
  299. #endif // !_LIBCPP_HAS_NO_THREADS
  300. template <class _To, class _Rep, class _Period>
  301. inline _LIBCPP_INLINE_VISIBILITY
  302. typename enable_if
  303. <
  304. chrono::__is_duration<_To>::value,
  305. _To
  306. >::type
  307. __ceil(chrono::duration<_Rep, _Period> __d)
  308. {
  309. using namespace chrono;
  310. _To __r = duration_cast<_To>(__d);
  311. if (__r < __d)
  312. ++__r;
  313. return __r;
  314. }
  315. #ifndef _LIBCPP_HAS_NO_THREADS
  316. template <class _Predicate>
  317. void
  318. condition_variable::wait(unique_lock<mutex>& __lk, _Predicate __pred)
  319. {
  320. while (!__pred())
  321. wait(__lk);
  322. }
  323. template <class _Clock, class _Duration>
  324. cv_status
  325. condition_variable::wait_until(unique_lock<mutex>& __lk,
  326. const chrono::time_point<_Clock, _Duration>& __t)
  327. {
  328. using namespace chrono;
  329. wait_for(__lk, __t - _Clock::now());
  330. return _Clock::now() < __t ? cv_status::no_timeout : cv_status::timeout;
  331. }
  332. template <class _Clock, class _Duration, class _Predicate>
  333. bool
  334. condition_variable::wait_until(unique_lock<mutex>& __lk,
  335. const chrono::time_point<_Clock, _Duration>& __t,
  336. _Predicate __pred)
  337. {
  338. while (!__pred())
  339. {
  340. if (wait_until(__lk, __t) == cv_status::timeout)
  341. return __pred();
  342. }
  343. return true;
  344. }
  345. template <class _Rep, class _Period>
  346. cv_status
  347. condition_variable::wait_for(unique_lock<mutex>& __lk,
  348. const chrono::duration<_Rep, _Period>& __d)
  349. {
  350. using namespace chrono;
  351. if (__d <= __d.zero())
  352. return cv_status::timeout;
  353. typedef time_point<system_clock, duration<long double, nano> > __sys_tpf;
  354. typedef time_point<system_clock, nanoseconds> __sys_tpi;
  355. __sys_tpf _Max = __sys_tpi::max();
  356. system_clock::time_point __s_now = system_clock::now();
  357. steady_clock::time_point __c_now = steady_clock::now();
  358. if (_Max - __d > __s_now)
  359. __do_timed_wait(__lk, __s_now + __ceil<nanoseconds>(__d));
  360. else
  361. __do_timed_wait(__lk, __sys_tpi::max());
  362. return steady_clock::now() - __c_now < __d ? cv_status::no_timeout :
  363. cv_status::timeout;
  364. }
  365. template <class _Rep, class _Period, class _Predicate>
  366. inline
  367. bool
  368. condition_variable::wait_for(unique_lock<mutex>& __lk,
  369. const chrono::duration<_Rep, _Period>& __d,
  370. _Predicate __pred)
  371. {
  372. return wait_until(__lk, chrono::steady_clock::now() + __d,
  373. _VSTD::move(__pred));
  374. }
  375. #endif // !_LIBCPP_HAS_NO_THREADS
  376. _LIBCPP_END_NAMESPACE_STD
  377. #endif // _LIBCPP___MUTEX_BASE