[lld][WebAssembly] Reinstate mistakenly disabled test. NFC
[llvm-project.git] / libcxx / include / mutex
blobb2a4d7993e0db85cb6bec1b2f9b8907858ee7608
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-exception
7 //
8 //===----------------------------------------------------------------------===//
10 #ifndef _LIBCPP_MUTEX
11 #define _LIBCPP_MUTEX
14     mutex synopsis
16 namespace std
19 class mutex
21 public:
22      constexpr mutex() noexcept;
23      ~mutex();
25     mutex(const mutex&) = delete;
26     mutex& operator=(const mutex&) = delete;
28     void lock();
29     bool try_lock();
30     void unlock();
32     typedef pthread_mutex_t* native_handle_type;
33     native_handle_type native_handle();
36 class recursive_mutex
38 public:
39      recursive_mutex();
40      ~recursive_mutex();
42     recursive_mutex(const recursive_mutex&) = delete;
43     recursive_mutex& operator=(const recursive_mutex&) = delete;
45     void lock();
46     bool try_lock() noexcept;
47     void unlock();
49     typedef pthread_mutex_t* native_handle_type;
50     native_handle_type native_handle();
53 class timed_mutex
55 public:
56      timed_mutex();
57      ~timed_mutex();
59     timed_mutex(const timed_mutex&) = delete;
60     timed_mutex& operator=(const timed_mutex&) = delete;
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();
71 class recursive_timed_mutex
73 public:
74      recursive_timed_mutex();
75      ~recursive_timed_mutex();
77     recursive_timed_mutex(const recursive_timed_mutex&) = delete;
78     recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete;
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();
89 struct defer_lock_t { explicit defer_lock_t() = default; };
90 struct try_to_lock_t { explicit try_to_lock_t() = default; };
91 struct adopt_lock_t { explicit adopt_lock_t() = default; };
93 inline constexpr defer_lock_t  defer_lock{};
94 inline constexpr try_to_lock_t try_to_lock{};
95 inline constexpr adopt_lock_t  adopt_lock{};
97 template <class Mutex>
98 class lock_guard
100 public:
101     typedef Mutex mutex_type;
103     explicit lock_guard(mutex_type& m);
104     lock_guard(mutex_type& m, adopt_lock_t);
105     ~lock_guard();
107     lock_guard(lock_guard const&) = delete;
108     lock_guard& operator=(lock_guard const&) = delete;
111 template <class... MutexTypes>
112 class scoped_lock // C++17
114 public:
115     using mutex_type = Mutex;  // Only if sizeof...(MutexTypes) == 1
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;
122 private:
123     tuple<MutexTypes&...> pm; // exposition only
126 template <class Mutex>
127 class unique_lock
129 public:
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();
142     unique_lock(unique_lock const&) = delete;
143     unique_lock& operator=(unique_lock const&) = delete;
145     unique_lock(unique_lock&& u) noexcept;
146     unique_lock& operator=(unique_lock&& u) noexcept;
148     void lock();
149     bool try_lock();
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);
156     void unlock();
158     void swap(unique_lock& u) noexcept;
159     mutex_type* release() noexcept;
161     bool owns_lock() const noexcept;
162     explicit operator bool () const noexcept;
163     mutex_type* mutex() const noexcept;
166 template <class Mutex>
167   void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) noexcept;
169 template <class L1, class L2, class... L3>
170   int try_lock(L1&, L2&, L3&...);
171 template <class L1, class L2, class... L3>
172   void lock(L1&, L2&, L3&...);
174 struct once_flag
176     constexpr once_flag() noexcept;
178     once_flag(const once_flag&) = delete;
179     once_flag& operator=(const once_flag&) = delete;
182 template<class Callable, class ...Args>
183   void call_once(once_flag& flag, Callable&& func, Args&&... args);
185 }  // std
189 #include <__config>
190 #include <__mutex_base>
191 #include <__threading_support>
192 #include <__utility/forward.h>
193 #include <cstdint>
194 #include <functional>
195 #include <memory>
196 #ifndef _LIBCPP_CXX03_LANG
197 # include <tuple>
198 #endif
199 #include <version>
201 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
202 #pragma GCC system_header
203 #endif
205 _LIBCPP_PUSH_MACROS
206 #include <__undef_macros>
209 _LIBCPP_BEGIN_NAMESPACE_STD
211 #ifndef _LIBCPP_HAS_NO_THREADS
213 class _LIBCPP_TYPE_VIS recursive_mutex
215     __libcpp_recursive_mutex_t __m_;
217 public:
218     recursive_mutex();
219     ~recursive_mutex();
221     recursive_mutex(const recursive_mutex&) = delete;
222     recursive_mutex& operator=(const recursive_mutex&) = delete;
224     void lock();
225     bool try_lock() _NOEXCEPT;
226     void unlock()  _NOEXCEPT;
228     typedef __libcpp_recursive_mutex_t* native_handle_type;
230     _LIBCPP_INLINE_VISIBILITY
231     native_handle_type native_handle() {return &__m_;}
234 class _LIBCPP_TYPE_VIS timed_mutex
236     mutex              __m_;
237     condition_variable __cv_;
238     bool               __locked_;
239 public:
240      timed_mutex();
241      ~timed_mutex();
243     timed_mutex(const timed_mutex&) = delete;
244     timed_mutex& operator=(const timed_mutex&) = delete;
246 public:
247     void lock();
248     bool try_lock() _NOEXCEPT;
249     template <class _Rep, class _Period>
250         _LIBCPP_INLINE_VISIBILITY
251         bool try_lock_for(const chrono::duration<_Rep, _Period>& __d)
252             {return try_lock_until(chrono::steady_clock::now() + __d);}
253     template <class _Clock, class _Duration>
254         _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
255         bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t);
256     void unlock() _NOEXCEPT;
259 template <class _Clock, class _Duration>
260 bool
261 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     {
270         __locked_ = true;
271         return true;
272     }
273     return false;
276 class _LIBCPP_TYPE_VIS recursive_timed_mutex
278     mutex              __m_;
279     condition_variable __cv_;
280     size_t             __count_;
281     __thread_id        __id_;
282 public:
283     recursive_timed_mutex();
284     ~recursive_timed_mutex();
286     recursive_timed_mutex(const recursive_timed_mutex&) = delete;
287     recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete;
289     void lock();
290     bool try_lock() _NOEXCEPT;
291     template <class _Rep, class _Period>
292         _LIBCPP_INLINE_VISIBILITY
293         bool try_lock_for(const chrono::duration<_Rep, _Period>& __d)
294             {return try_lock_until(chrono::steady_clock::now() + __d);}
295     template <class _Clock, class _Duration>
296         _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
297         bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t);
298     void unlock() _NOEXCEPT;
301 template <class _Clock, class _Duration>
302 bool
303 recursive_timed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t)
305     using namespace chrono;
306     __thread_id __id = this_thread::get_id();
307     unique_lock<mutex> lk(__m_);
308     if (__id == __id_)
309     {
310         if (__count_ == numeric_limits<size_t>::max())
311             return false;
312         ++__count_;
313         return true;
314     }
315     bool no_timeout = _Clock::now() < __t;
316     while (no_timeout && __count_ != 0)
317         no_timeout = __cv_.wait_until(lk, __t) == cv_status::no_timeout;
318     if (__count_ == 0)
319     {
320         __count_ = 1;
321         __id_ = __id;
322         return true;
323     }
324     return false;
327 template <class _L0, class _L1>
329 try_lock(_L0& __l0, _L1& __l1)
331     unique_lock<_L0> __u0(__l0, try_to_lock);
332     if (__u0.owns_lock())
333     {
334         if (__l1.try_lock())
335         {
336             __u0.release();
337             return -1;
338         }
339         else
340             return 1;
341     }
342     return 0;
345 #ifndef _LIBCPP_CXX03_LANG
347 template <class _L0, class _L1, class _L2, class... _L3>
349 try_lock(_L0& __l0, _L1& __l1, _L2& __l2, _L3&... __l3)
351     int __r = 0;
352     unique_lock<_L0> __u0(__l0, try_to_lock);
353     if (__u0.owns_lock())
354     {
355         __r = try_lock(__l1, __l2, __l3...);
356         if (__r == -1)
357             __u0.release();
358         else
359             ++__r;
360     }
361     return __r;
364 #endif // _LIBCPP_CXX03_LANG
366 template <class _L0, class _L1>
367 void
368 lock(_L0& __l0, _L1& __l1)
370     while (true)
371     {
372         {
373             unique_lock<_L0> __u0(__l0);
374             if (__l1.try_lock())
375             {
376                 __u0.release();
377                 break;
378             }
379         }
380         __libcpp_thread_yield();
381         {
382             unique_lock<_L1> __u1(__l1);
383             if (__l0.try_lock())
384             {
385                 __u1.release();
386                 break;
387             }
388         }
389         __libcpp_thread_yield();
390     }
393 #ifndef _LIBCPP_CXX03_LANG
395 template <class _L0, class _L1, class _L2, class ..._L3>
396 void
397 __lock_first(int __i, _L0& __l0, _L1& __l1, _L2& __l2, _L3& ...__l3)
399     while (true)
400     {
401         switch (__i)
402         {
403         case 0:
404             {
405                 unique_lock<_L0> __u0(__l0);
406                 __i = try_lock(__l1, __l2, __l3...);
407                 if (__i == -1)
408                 {
409                     __u0.release();
410                     return;
411                 }
412             }
413             ++__i;
414             __libcpp_thread_yield();
415             break;
416         case 1:
417             {
418                 unique_lock<_L1> __u1(__l1);
419                 __i = try_lock(__l2, __l3..., __l0);
420                 if (__i == -1)
421                 {
422                     __u1.release();
423                     return;
424                 }
425             }
426             if (__i == sizeof...(_L3) + 1)
427                 __i = 0;
428             else
429                 __i += 2;
430             __libcpp_thread_yield();
431             break;
432         default:
433             __lock_first(__i - 2, __l2, __l3..., __l0, __l1);
434             return;
435         }
436     }
439 template <class _L0, class _L1, class _L2, class ..._L3>
440 inline _LIBCPP_INLINE_VISIBILITY
441 void
442 lock(_L0& __l0, _L1& __l1, _L2& __l2, _L3& ...__l3)
444     __lock_first(0, __l0, __l1, __l2, __l3...);
447 template <class _L0>
448 inline _LIBCPP_INLINE_VISIBILITY
449 void __unlock(_L0& __l0) {
450     __l0.unlock();
453 template <class _L0, class _L1>
454 inline _LIBCPP_INLINE_VISIBILITY
455 void __unlock(_L0& __l0, _L1& __l1) {
456     __l0.unlock();
457     __l1.unlock();
460 template <class _L0, class _L1, class _L2, class ..._L3>
461 inline _LIBCPP_INLINE_VISIBILITY
462 void __unlock(_L0& __l0, _L1& __l1, _L2& __l2, _L3&... __l3) {
463     __l0.unlock();
464     __l1.unlock();
465     _VSTD::__unlock(__l2, __l3...);
468 #endif // _LIBCPP_CXX03_LANG
470 #if _LIBCPP_STD_VER > 14
471 template <class ..._Mutexes>
472 class _LIBCPP_TEMPLATE_VIS scoped_lock;
474 template <>
475 class _LIBCPP_TEMPLATE_VIS scoped_lock<> {
476 public:
477     explicit scoped_lock() {}
478     ~scoped_lock() = default;
480     _LIBCPP_INLINE_VISIBILITY
481     explicit scoped_lock(adopt_lock_t) {}
483     scoped_lock(scoped_lock const&) = delete;
484     scoped_lock& operator=(scoped_lock const&) = delete;
487 template <class _Mutex>
488 class _LIBCPP_TEMPLATE_VIS _LIBCPP_THREAD_SAFETY_ANNOTATION(scoped_lockable) scoped_lock<_Mutex> {
489 public:
490     typedef _Mutex  mutex_type;
491 private:
492     mutex_type& __m_;
493 public:
494     explicit scoped_lock(mutex_type & __m) _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability(__m))
495         : __m_(__m) {__m_.lock();}
497     ~scoped_lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability()) {__m_.unlock();}
499     _LIBCPP_INLINE_VISIBILITY
500     explicit scoped_lock(adopt_lock_t, mutex_type& __m) _LIBCPP_THREAD_SAFETY_ANNOTATION(requires_capability(__m))
501         : __m_(__m) {}
503     scoped_lock(scoped_lock const&) = delete;
504     scoped_lock& operator=(scoped_lock const&) = delete;
507 template <class ..._MArgs>
508 class _LIBCPP_TEMPLATE_VIS scoped_lock
510     static_assert(sizeof...(_MArgs) > 1, "At least 2 lock types required");
511     typedef tuple<_MArgs&...> _MutexTuple;
513 public:
514     _LIBCPP_INLINE_VISIBILITY
515     explicit scoped_lock(_MArgs&... __margs)
516       : __t_(__margs...)
517     {
518         _VSTD::lock(__margs...);
519     }
521     _LIBCPP_INLINE_VISIBILITY
522     scoped_lock(adopt_lock_t, _MArgs&... __margs)
523         : __t_(__margs...)
524     {
525     }
527     _LIBCPP_INLINE_VISIBILITY
528     ~scoped_lock() {
529         typedef typename __make_tuple_indices<sizeof...(_MArgs)>::type _Indices;
530         __unlock_unpack(_Indices{}, __t_);
531     }
533     scoped_lock(scoped_lock const&) = delete;
534     scoped_lock& operator=(scoped_lock const&) = delete;
536 private:
537     template <size_t ..._Indx>
538     _LIBCPP_INLINE_VISIBILITY
539     static void __unlock_unpack(__tuple_indices<_Indx...>, _MutexTuple& __mt) {
540         _VSTD::__unlock(_VSTD::get<_Indx>(__mt)...);
541     }
543     _MutexTuple __t_;
546 #endif // _LIBCPP_STD_VER > 14
547 #endif // !_LIBCPP_HAS_NO_THREADS
549 struct _LIBCPP_TEMPLATE_VIS once_flag;
551 #ifndef _LIBCPP_CXX03_LANG
553 template<class _Callable, class... _Args>
554 _LIBCPP_INLINE_VISIBILITY
555 void call_once(once_flag&, _Callable&&, _Args&&...);
557 #else  // _LIBCPP_CXX03_LANG
559 template<class _Callable>
560 _LIBCPP_INLINE_VISIBILITY
561 void call_once(once_flag&, _Callable&);
563 template<class _Callable>
564 _LIBCPP_INLINE_VISIBILITY
565 void call_once(once_flag&, const _Callable&);
567 #endif // _LIBCPP_CXX03_LANG
569 struct _LIBCPP_TEMPLATE_VIS once_flag
571     _LIBCPP_INLINE_VISIBILITY
572     _LIBCPP_CONSTEXPR
573         once_flag() _NOEXCEPT : __state_(0) {}
574     once_flag(const once_flag&) = delete;
575     once_flag& operator=(const once_flag&) = delete;
577 #if defined(_LIBCPP_ABI_MICROSOFT)
578    typedef uintptr_t _State_type;
579 #else
580    typedef unsigned long _State_type;
581 #endif
583 private:
584     _State_type __state_;
586 #ifndef _LIBCPP_CXX03_LANG
587     template<class _Callable, class... _Args>
588     friend
589     void call_once(once_flag&, _Callable&&, _Args&&...);
590 #else  // _LIBCPP_CXX03_LANG
591     template<class _Callable>
592     friend
593     void call_once(once_flag&, _Callable&);
595     template<class _Callable>
596     friend
597     void call_once(once_flag&, const _Callable&);
598 #endif // _LIBCPP_CXX03_LANG
601 #ifndef _LIBCPP_CXX03_LANG
603 template <class _Fp>
604 class __call_once_param
606     _Fp& __f_;
607 public:
608     _LIBCPP_INLINE_VISIBILITY
609     explicit __call_once_param(_Fp& __f) : __f_(__f) {}
611     _LIBCPP_INLINE_VISIBILITY
612     void operator()()
613     {
614         typedef typename __make_tuple_indices<tuple_size<_Fp>::value, 1>::type _Index;
615         __execute(_Index());
616     }
618 private:
619     template <size_t ..._Indices>
620     _LIBCPP_INLINE_VISIBILITY
621     void __execute(__tuple_indices<_Indices...>)
622     {
623         _VSTD::__invoke(_VSTD::get<0>(_VSTD::move(__f_)), _VSTD::get<_Indices>(_VSTD::move(__f_))...);
624     }
627 #else
629 template <class _Fp>
630 class __call_once_param
632     _Fp& __f_;
633 public:
634     _LIBCPP_INLINE_VISIBILITY
635     explicit __call_once_param(_Fp& __f) : __f_(__f) {}
637     _LIBCPP_INLINE_VISIBILITY
638     void operator()()
639     {
640         __f_();
641     }
644 #endif
646 template <class _Fp>
647 void _LIBCPP_INLINE_VISIBILITY
648 __call_once_proxy(void* __vp)
650     __call_once_param<_Fp>* __p = static_cast<__call_once_param<_Fp>*>(__vp);
651     (*__p)();
654 _LIBCPP_FUNC_VIS void __call_once(volatile once_flag::_State_type&, void*,
655                                   void (*)(void*));
657 #ifndef _LIBCPP_CXX03_LANG
659 template<class _Callable, class... _Args>
660 inline _LIBCPP_INLINE_VISIBILITY
661 void
662 call_once(once_flag& __flag, _Callable&& __func, _Args&&... __args)
664     if (__libcpp_acquire_load(&__flag.__state_) != ~once_flag::_State_type(0))
665     {
666         typedef tuple<_Callable&&, _Args&&...> _Gp;
667         _Gp __f(_VSTD::forward<_Callable>(__func), _VSTD::forward<_Args>(__args)...);
668         __call_once_param<_Gp> __p(__f);
669         __call_once(__flag.__state_, &__p, &__call_once_proxy<_Gp>);
670     }
673 #else  // _LIBCPP_CXX03_LANG
675 template<class _Callable>
676 inline _LIBCPP_INLINE_VISIBILITY
677 void
678 call_once(once_flag& __flag, _Callable& __func)
680     if (__libcpp_acquire_load(&__flag.__state_) != ~once_flag::_State_type(0))
681     {
682         __call_once_param<_Callable> __p(__func);
683         __call_once(__flag.__state_, &__p, &__call_once_proxy<_Callable>);
684     }
687 template<class _Callable>
688 inline _LIBCPP_INLINE_VISIBILITY
689 void
690 call_once(once_flag& __flag, const _Callable& __func)
692     if (__libcpp_acquire_load(&__flag.__state_) != ~once_flag::_State_type(0))
693     {
694         __call_once_param<const _Callable> __p(__func);
695         __call_once(__flag.__state_, &__p, &__call_once_proxy<const _Callable>);
696     }
699 #endif // _LIBCPP_CXX03_LANG
701 _LIBCPP_END_NAMESPACE_STD
703 _LIBCPP_POP_MACROS
705 #endif // _LIBCPP_MUTEX