SeqAn3 3.4.0-rc.1
The Modern C++ library for sequence analysis.
Loading...
Searching...
No Matches
latch.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2006-2024 Knut Reinert & Freie Universität Berlin
2// SPDX-FileCopyrightText: 2016-2024 Knut Reinert & MPI für molekulare Genetik
3// SPDX-License-Identifier: BSD-3-Clause
4
10#pragma once
11
12#include <atomic>
13#include <cassert>
14#include <seqan3/std/new>
15
17
18namespace seqan3::detail
19{
20
35class latch
36{
37public:
42 latch() = delete;
43 latch(latch const &) = delete;
44 latch(latch &&) = delete;
45 latch & operator=(latch const &) = delete;
46 latch & operator=(latch &&) = delete;
47
50 {
51 spin_delay delay{};
52 while (num_waiting.load(std::memory_order_acquire) > 0)
53 delay.wait(); // LCOV_EXCL_LINE
54 }
55
59 explicit latch(ptrdiff_t const expected) : counter{expected}
60 {
61 assert(expected >= 0);
62 num_waiting.store(0, std::memory_order_relaxed);
63 }
65
82 void arrive(ptrdiff_t n = 1) noexcept
83 {
84 assert(counter.load(std::memory_order_acquire) >= n);
85 assert(counter.load(std::memory_order_acquire) >= 0);
86
87 counter.fetch_sub(n, std::memory_order_acq_rel);
88 }
89
107 void arrive_and_wait(ptrdiff_t n = 1) noexcept
108 {
109 ++num_waiting; // ensure that destructor is not finished in-between the arrive and wait call.
110 arrive(n);
111 wait();
112 --num_waiting;
113 }
114
125 bool try_wait() const noexcept
126 {
127 return counter.load(std::memory_order_acquire) == 0;
128 }
129
145 void wait() const
146 {
147 ++num_waiting; // register waiting thread to synchronise with destructor.
148 spin_delay delay{};
149 while (counter.load(std::memory_order_acquire) > 0)
150 delay.wait();
151 --num_waiting;
152 }
153
154private:
159};
160
161} // namespace seqan3::detail
A single-use synchronisation point to coordinate concurrent threads.
Definition latch.hpp:36
latch()=delete
Deleted.
latch & operator=(latch const &)=delete
Deleted.
latch(latch const &)=delete
Deleted.
std::atomic< std::ptrdiff_t > counter
The number of participating threads.
Definition latch.hpp:156
bool try_wait() const noexcept
Checks if all participating threads have reached the synchronisation point.
Definition latch.hpp:125
void wait() const
Waits for all participating threads to arrive at the synchronisation point.
Definition latch.hpp:145
latch(ptrdiff_t const expected)
Constructs the latch with the expected number of threads.
Definition latch.hpp:59
~latch()
Destructs the latch and waits for all participating threads to arrive.
Definition latch.hpp:49
std::atomic< std::ptrdiff_t > num_waiting
The number of waiting threads.
Definition latch.hpp:158
void arrive(ptrdiff_t n=1) noexcept
Atomically decrements counter by n.
Definition latch.hpp:82
void arrive_and_wait(ptrdiff_t n=1) noexcept
Atomically decrements counter by n and blocks the calling thread.
Definition latch.hpp:107
latch & operator=(latch &&)=delete
Deleted.
latch(latch &&)=delete
Deleted.
A delay for threads waiting for a shared resource.
Definition spin_delay.hpp:41
void wait()
Delays the calling thread by either using active spinning or passive spinning.
Definition spin_delay.hpp:62
T fetch_sub(T... args)
constexpr std::size_t hardware_destructive_interference_size
Minimum offset between two objects to avoid false sharing.
Definition new:54
T load(T... args)
The internal SeqAn3 namespace.
Definition aligned_sequence_concept.hpp:26
The <new> header from C++17's standard library.
Provides seqan3::detail::spin_delay.
T store(T... args)
Hide me