brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.8 KiB · 33268d9 Raw
138 lines · plain
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-exception7//8//===----------------------------------------------------------------------===//9 10#ifndef _LIBCPP_LATCH11#define _LIBCPP_LATCH12 13/*14    latch synopsis15 16namespace std17{18 19  class latch                                     // since C++2020  {21  public:22    static constexpr ptrdiff_t max() noexcept;23 24    constexpr explicit latch(ptrdiff_t __expected);25    ~latch();26 27    latch(const latch&) = delete;28    latch& operator=(const latch&) = delete;29 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);34 35  private:36    ptrdiff_t __counter; // exposition only37  };38 39}40 41*/42 43#if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)44#  include <__cxx03/__config>45#else46#  include <__config>47 48#  if _LIBCPP_HAS_THREADS49 50#    include <__assert>51#    include <__atomic/atomic.h>52#    include <__atomic/atomic_sync.h>53#    include <__atomic/memory_order.h>54#    include <__cstddef/ptrdiff_t.h>55#    include <limits>56#    include <version>57 58#    if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)59#      pragma GCC system_header60#    endif61 62_LIBCPP_PUSH_MACROS63#    include <__undef_macros>64 65#    if _LIBCPP_STD_VER >= 2066 67_LIBCPP_BEGIN_NAMESPACE_STD68 69class latch {70  atomic<ptrdiff_t> __a_;71 72public:73  [[nodiscard]] static _LIBCPP_HIDE_FROM_ABI constexpr ptrdiff_t max() noexcept {74    return numeric_limits<ptrdiff_t>::max();75  }76 77  inline _LIBCPP_HIDE_FROM_ABI constexpr explicit latch(ptrdiff_t __expected) : __a_(__expected) {78    _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(79        __expected >= 0,80        "latch::latch(ptrdiff_t): latch cannot be "81        "initialized with a negative value");82    _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(83        __expected <= max(),84        "latch::latch(ptrdiff_t): latch cannot be "85        "initialized with a value greater than max()");86  }87 88  _LIBCPP_HIDE_FROM_ABI ~latch() = default;89  latch(const latch&)            = delete;90  latch& operator=(const latch&) = delete;91 92  inline _LIBCPP_HIDE_FROM_ABI void count_down(ptrdiff_t __update = 1) {93    _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(__update >= 0, "latch::count_down called with a negative value");94    auto const __old = __a_.fetch_sub(__update, memory_order_release);95    _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(96        __update <= __old,97        "latch::count_down called with a value greater "98        "than the internal counter");99    if (__old == __update)100      __a_.notify_all();101  }102  [[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool try_wait() const noexcept {103    auto __value = __a_.load(memory_order_acquire);104    return try_wait_impl(__value);105  }106  inline _LIBCPP_HIDE_FROM_ABI void wait() const {107    std::__atomic_wait_unless(__a_, memory_order_acquire, [this](ptrdiff_t& __value) -> bool {108      return try_wait_impl(__value);109    });110  }111  inline _LIBCPP_HIDE_FROM_ABI void arrive_and_wait(ptrdiff_t __update = 1) {112    _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(__update >= 0, "latch::arrive_and_wait called with a negative value");113    // other preconditions on __update are checked in count_down()114 115    count_down(__update);116    wait();117  }118 119private:120  _LIBCPP_HIDE_FROM_ABI bool try_wait_impl(ptrdiff_t& __value) const noexcept { return __value == 0; }121};122 123_LIBCPP_END_NAMESPACE_STD124 125#    endif // _LIBCPP_STD_VER >= 20126 127_LIBCPP_POP_MACROS128 129#  endif // _LIBCPP_HAS_THREADS130 131#  if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20132#    include <atomic>133#    include <cstddef>134#  endif135#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)136 137#endif // _LIBCPP_LATCH138