YACLib
C++ library for concurrent tasks execution
Loading...
Searching...
No Matches
atomic_counter.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <yaclib/config.hpp>
5
6#include <cstddef>
7#include <utility>
8#include <yaclib_std/atomic>
9
10namespace yaclib::detail {
11
12template <typename CounterBase, typename Deleter = DefaultDeleter>
14 template <typename... Args>
15 AtomicCounter(std::size_t n, Args&&... args) noexcept(std::is_nothrow_constructible_v<CounterBase, Args&&...>)
16 : CounterBase{std::forward<Args>(args)...}, count{n} {
17 }
18
19 YACLIB_INLINE void Add(std::size_t delta) noexcept {
20 count.fetch_add(delta, std::memory_order_relaxed);
21 }
22
23 YACLIB_INLINE void Sub(std::size_t delta) noexcept {
24 if (SubEqual(delta)) {
25 Deleter::Delete(*this);
26 }
27 }
28
29 [[nodiscard]] std::size_t GetRef() const noexcept {
30 // Dangerous! Use only to sync with release or if synchronization is not needed
31 return count.load(std::memory_order_acquire);
32 }
33
34 [[nodiscard]] YACLIB_INLINE bool SubEqual(std::size_t n) noexcept {
35#ifdef YACLIB_TSAN
36 return count.fetch_sub(n, std::memory_order_acq_rel) == n;
37#else
38 // Thread Sanitizer have false positive error with std::atomic_thread_fence
39 // https://www.boost.org/doc/libs/1_76_0/doc/html/atomic/usage_examples.html#boost_atomic.usage_examples.example_reference_counters
40 if (count.fetch_sub(n, std::memory_order_release) == n) {
41 yaclib_std::atomic_thread_fence(std::memory_order_acquire);
42 return true;
43 }
44 return false;
45#endif
46 }
47
49};
50
51} // namespace yaclib::detail
atomic< std::size_t > atomic_size_t
Definition atomic.hpp:86
Contract< V, E > MakeContract()
Creates related future and promise.
Definition contract.hpp:25
YACLIB_INLINE bool SubEqual(std::size_t n) noexcept
YACLIB_INLINE void Sub(std::size_t delta) noexcept
yaclib_std::atomic_size_t count
std::size_t GetRef() const noexcept
YACLIB_INLINE void Add(std::size_t delta) noexcept
AtomicCounter(std::size_t n, Args &&... args) noexcept(std::is_nothrow_constructible_v< CounterBase, Args &&... >)