Warning, /include/c++/v1/latch 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_LATCH
0011 #define _LIBCPP_LATCH
0012
0013 /*
0014 latch synopsis
0015
0016 namespace std
0017 {
0018
0019 class latch // since C++20
0020 {
0021 public:
0022 static constexpr ptrdiff_t max() noexcept;
0023
0024 constexpr explicit latch(ptrdiff_t __expected);
0025 ~latch();
0026
0027 latch(const latch&) = delete;
0028 latch& operator=(const latch&) = delete;
0029
0030 void count_down(ptrdiff_t __update = 1);
0031 bool try_wait() const noexcept;
0032 void wait() const;
0033 void arrive_and_wait(ptrdiff_t __update = 1);
0034
0035 private:
0036 ptrdiff_t __counter; // exposition only
0037 };
0038
0039 }
0040
0041 */
0042
0043 #if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
0044 # include <__cxx03/latch>
0045 #else
0046 # include <__config>
0047
0048 # if _LIBCPP_HAS_THREADS
0049
0050 # include <__assert>
0051 # include <__atomic/atomic.h>
0052 # include <__atomic/atomic_sync.h>
0053 # include <__atomic/memory_order.h>
0054 # include <__cstddef/ptrdiff_t.h>
0055 # include <limits>
0056 # include <version>
0057
0058 # if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0059 # pragma GCC system_header
0060 # endif
0061
0062 _LIBCPP_PUSH_MACROS
0063 # include <__undef_macros>
0064
0065 # if _LIBCPP_STD_VER >= 20
0066
0067 _LIBCPP_BEGIN_NAMESPACE_STD
0068
0069 class latch {
0070 atomic<ptrdiff_t> __a_;
0071
0072 public:
0073 static _LIBCPP_HIDE_FROM_ABI constexpr ptrdiff_t max() noexcept { return numeric_limits<ptrdiff_t>::max(); }
0074
0075 inline _LIBCPP_HIDE_FROM_ABI constexpr explicit latch(ptrdiff_t __expected) : __a_(__expected) {
0076 _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
0077 __expected >= 0,
0078 "latch::latch(ptrdiff_t): latch cannot be "
0079 "initialized with a negative value");
0080 _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
0081 __expected <= max(),
0082 "latch::latch(ptrdiff_t): latch cannot be "
0083 "initialized with a value greater than max()");
0084 }
0085
0086 _LIBCPP_HIDE_FROM_ABI ~latch() = default;
0087 latch(const latch&) = delete;
0088 latch& operator=(const latch&) = delete;
0089
0090 inline _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void count_down(ptrdiff_t __update = 1) {
0091 _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(__update >= 0, "latch::count_down called with a negative value");
0092 auto const __old = __a_.fetch_sub(__update, memory_order_release);
0093 _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
0094 __update <= __old,
0095 "latch::count_down called with a value greater "
0096 "than the internal counter");
0097 if (__old == __update)
0098 __a_.notify_all();
0099 }
0100 inline _LIBCPP_HIDE_FROM_ABI bool try_wait() const noexcept {
0101 auto __value = __a_.load(memory_order_acquire);
0102 return try_wait_impl(__value);
0103 }
0104 inline _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void wait() const {
0105 std::__atomic_wait_unless(__a_, memory_order_acquire, [this](ptrdiff_t& __value) -> bool {
0106 return try_wait_impl(__value);
0107 });
0108 }
0109 inline _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void arrive_and_wait(ptrdiff_t __update = 1) {
0110 _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(__update >= 0, "latch::arrive_and_wait called with a negative value");
0111 // other preconditions on __update are checked in count_down()
0112
0113 count_down(__update);
0114 wait();
0115 }
0116
0117 private:
0118 _LIBCPP_HIDE_FROM_ABI bool try_wait_impl(ptrdiff_t& __value) const noexcept { return __value == 0; }
0119 };
0120
0121 _LIBCPP_END_NAMESPACE_STD
0122
0123 # endif // _LIBCPP_STD_VER >= 20
0124
0125 _LIBCPP_POP_MACROS
0126
0127 # endif // _LIBCPP_HAS_THREADS
0128
0129 # if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
0130 # include <atomic>
0131 # include <cstddef>
0132 # endif
0133 #endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
0134
0135 #endif // _LIBCPP_LATCH