Back to home page

EIC code displayed by LXR

 
 

    


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