SeqAn3 3.1.0
The Modern C++ library for sequence analysis.
latch.hpp
Go to the documentation of this file.
1// -----------------------------------------------------------------------------------------------------
2// Copyright (c) 2006-2021, Knut Reinert & Freie Universität Berlin
3// Copyright (c) 2016-2021, Knut Reinert & MPI für molekulare Genetik
4// This file may be used, modified and/or redistributed under the terms of the 3-clause BSD-License
5// shipped with this file and also available at: https://github.com/seqan/seqan3/blob/master/LICENSE.md
6// -----------------------------------------------------------------------------------------------------
7
13#pragma once
14
15#include <atomic>
16#include <cassert>
17#include <seqan3/std/new>
18
20
21namespace seqan3::detail
22{
23
38class latch
39{
40public:
41
46 latch() = delete;
47 latch(latch const &) = delete;
48 latch(latch &&) = delete;
49 latch & operator=(latch const &) = delete;
50 latch & operator=(latch &&) = delete;
51
53 ~latch()
54 {
55 spin_delay delay{};
56 while (num_waiting.load(std::memory_order_acquire) > 0)
57 delay.wait();
58 }
59
63 explicit latch(ptrdiff_t const expected) :
64 counter{expected}
65 {
66 assert(expected >= 0);
67 num_waiting.store(0, std::memory_order_relaxed);
68 }
70
87 void arrive(ptrdiff_t n = 1) noexcept
88 {
89 assert(counter.load(std::memory_order_acquire) >= n);
90 assert(counter.load(std::memory_order_acquire) >= 0);
91
92 counter.fetch_sub(n, std::memory_order_acq_rel);
93 }
94
112 void arrive_and_wait(ptrdiff_t n = 1) noexcept
113 {
114 ++num_waiting; // ensure that destructor is not finished in-between the arrive and wait call.
115 arrive(n);
116 wait();
117 --num_waiting;
118 }
119
130 bool try_wait() const noexcept
131 {
132 return counter.load(std::memory_order_acquire) == 0;
133 }
134
150 void wait() const
151 {
152 ++num_waiting; // register waiting thread to synchronise with destructor.
153 spin_delay delay{};
154 while (counter.load(std::memory_order_acquire) > 0)
155 delay.wait();
156 --num_waiting;
157 }
158
159private:
160
165};
166
167} // namespace seqan3::detail
constexpr std::size_t hardware_destructive_interference_size
Minimum offset between two objects to avoid false sharing.
Definition: new:32
The <new> header from C++17's standard library.
Provides seqan3::detail::spin_delay.