[rtsan] Remove mkfifoat interceptor (#116997)
[llvm-project.git] / libcxx / include / latch
blob1860ed816c856201ab90217051989d7470ed1bf5
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_LATCH
11 #define _LIBCPP_LATCH
14     latch synopsis
16 namespace std
19   class latch                                     // since C++20
20   {
21   public:
22     static constexpr ptrdiff_t max() noexcept;
24     constexpr explicit latch(ptrdiff_t __expected);
25     ~latch();
27     latch(const latch&) = delete;
28     latch& operator=(const latch&) = delete;
30     void count_down(ptrdiff_t __update = 1);
31     bool try_wait() const noexcept;
32     void wait() const;
33     void arrive_and_wait(ptrdiff_t __update = 1);
35   private:
36     ptrdiff_t __counter; // exposition only
37   };
43 #include <__config>
45 #if _LIBCPP_HAS_THREADS
47 #  include <__assert>
48 #  include <__atomic/atomic.h>
49 #  include <__atomic/atomic_sync.h>
50 #  include <__atomic/memory_order.h>
51 #  include <__cstddef/ptrdiff_t.h>
52 #  include <limits>
53 #  include <version>
55 #  if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
56 #    pragma GCC system_header
57 #  endif
59 _LIBCPP_PUSH_MACROS
60 #  include <__undef_macros>
62 #  if _LIBCPP_STD_VER >= 20
64 _LIBCPP_BEGIN_NAMESPACE_STD
66 class latch {
67   atomic<ptrdiff_t> __a_;
69 public:
70   static _LIBCPP_HIDE_FROM_ABI constexpr ptrdiff_t max() noexcept { return numeric_limits<ptrdiff_t>::max(); }
72   inline _LIBCPP_HIDE_FROM_ABI constexpr explicit latch(ptrdiff_t __expected) : __a_(__expected) {
73     _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
74         __expected >= 0,
75         "latch::latch(ptrdiff_t): latch cannot be "
76         "initialized with a negative value");
77     _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
78         __expected <= max(),
79         "latch::latch(ptrdiff_t): latch cannot be "
80         "initialized with a value greater than max()");
81   }
83   _LIBCPP_HIDE_FROM_ABI ~latch() = default;
84   latch(const latch&)            = delete;
85   latch& operator=(const latch&) = delete;
87   inline _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void count_down(ptrdiff_t __update = 1) {
88     _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(__update >= 0, "latch::count_down called with a negative value");
89     auto const __old = __a_.fetch_sub(__update, memory_order_release);
90     _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
91         __update <= __old,
92         "latch::count_down called with a value greater "
93         "than the internal counter");
94     if (__old == __update)
95       __a_.notify_all();
96   }
97   inline _LIBCPP_HIDE_FROM_ABI bool try_wait() const noexcept {
98     auto __value = __a_.load(memory_order_acquire);
99     return try_wait_impl(__value);
100   }
101   inline _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void wait() const {
102     std::__atomic_wait_unless(
103         __a_, [this](ptrdiff_t& __value) -> bool { return try_wait_impl(__value); }, memory_order_acquire);
104   }
105   inline _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void arrive_and_wait(ptrdiff_t __update = 1) {
106     _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(__update >= 0, "latch::arrive_and_wait called with a negative value");
107     // other preconditions on __update are checked in count_down()
109     count_down(__update);
110     wait();
111   }
113 private:
114   _LIBCPP_HIDE_FROM_ABI bool try_wait_impl(ptrdiff_t& __value) const noexcept { return __value == 0; }
117 _LIBCPP_END_NAMESPACE_STD
119 #  endif // _LIBCPP_STD_VER >= 20
121 _LIBCPP_POP_MACROS
123 #endif // _LIBCPP_HAS_THREADS
125 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
126 #  include <atomic>
127 #  include <cstddef>
128 #endif
130 #endif // _LIBCPP_LATCH