codekingpro/portable-devtools
114k
1// -*- C++ -*-2//===--------------------------- latch -----------------------------------===//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 _LIBCUDACXX_LATCH11#define _LIBCUDACXX_LATCH12 13/*14 latch synopsis15 16namespace std17{18 19 class latch20 {21 public:22 constexpr explicit latch(ptrdiff_t __expected);23 ~latch();24 25 latch(const latch&) = delete;26 latch& operator=(const latch&) = delete;27 28 void count_down(ptrdiff_t __update = 1);29 bool try_wait() const noexcept;30 void wait() const;31 void arrive_and_wait(ptrdiff_t __update = 1);32 33 private:34 ptrdiff_t __counter; // exposition only35 };36 37}38 39*/40 41#ifndef __cuda_std__42#include <__config>43#endif // __cuda_std__44 45#include "__assert" // all public C++ headers provide the assertion handler46#include "__debug"47#include "atomic"48 49#ifndef __cuda_std__50#include <__pragma_push>51#endif // __cuda_std__52 53#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)54# pragma GCC system_header55#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)56# pragma clang system_header57#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)58# pragma system_header59#endif // no system header60 61#ifdef _LIBCUDACXX_HAS_NO_THREADS62# error <latch> is not supported on this single threaded system63#endif64 65_LIBCUDACXX_BEGIN_NAMESPACE_STD66 67# if _LIBCUDACXX_CUDA_ABI_VERSION < 368# define _LIBCUDACXX_LATCH_ALIGNMENT alignas(64)69# else70# define _LIBCUDACXX_LATCH_ALIGNMENT71# endif72 73template<int _Sco = 0>74class __latch_base75{76 _LIBCUDACXX_LATCH_ALIGNMENT __atomic_base<ptrdiff_t, _Sco> __counter;77public:78 inline _LIBCUDACXX_INLINE_VISIBILITY constexpr79 explicit __latch_base(ptrdiff_t __expected)80 : __counter(__expected) { }81 82 ~__latch_base() = default;83 __latch_base(const __latch_base&) = delete;84 __latch_base& operator=(const __latch_base&) = delete;85 86 inline _LIBCUDACXX_INLINE_VISIBILITY87 void count_down(ptrdiff_t __update = 1)88 {89 _LIBCUDACXX_ASSERT(__update > 0, "");90 auto const __old = __counter.fetch_sub(__update, memory_order_release);91 _LIBCUDACXX_ASSERT(__old >= __update, "");92 if(__old == __update)93 __counter.notify_all();94 }95 inline _LIBCUDACXX_INLINE_VISIBILITY96 bool try_wait() const noexcept97 {98 return __counter.load(memory_order_acquire) == 0;99 }100 inline _LIBCUDACXX_INLINE_VISIBILITY101 void wait() const102 {103 while(1) {104 auto const __current = __counter.load(memory_order_acquire);105 if(__current == 0)106 return;107 __counter.wait(__current, memory_order_relaxed)108 ;109 }110 }111 inline _LIBCUDACXX_INLINE_VISIBILITY112 void arrive_and_wait(ptrdiff_t __update = 1)113 {114 count_down(__update);115 wait();116 }117 118 _LIBCUDACXX_INLINE_VISIBILITY119 static constexpr ptrdiff_t max() noexcept120 {121 return numeric_limits<ptrdiff_t>::max();122 }123};124 125using latch = __latch_base<>;126 127_LIBCUDACXX_END_NAMESPACE_STD128 129#ifndef __cuda_std__130#include <__pragma_pop>131#else132#include "__cuda/latch.h"133#endif //__cuda_std__134 135#endif //_LIBCUDACXX_LATCH136 