SeqAn3 3.2.0
The Modern C++ library for sequence analysis.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
latch.hpp
Go to the documentation of this file.
1// -----------------------------------------------------------------------------------------------------
2// Copyright (c) 2006-2022, Knut Reinert & Freie Universität Berlin
3// Copyright (c) 2016-2022, 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:
45 latch() = delete;
46 latch(latch const &) = delete;
47 latch(latch &&) = delete;
48 latch & operator=(latch const &) = delete;
49 latch & operator=(latch &&) = delete;
50
52 ~latch()
53 {
54 spin_delay delay{};
55 while (num_waiting.load(std::memory_order_acquire) > 0)
56 delay.wait();
57 }
58
62 explicit latch(ptrdiff_t const expected) : counter{expected}
63 {
64 assert(expected >= 0);
65 num_waiting.store(0, std::memory_order_relaxed);
66 }
68
85 void arrive(ptrdiff_t n = 1) noexcept
86 {
87 assert(counter.load(std::memory_order_acquire) >= n);
88 assert(counter.load(std::memory_order_acquire) >= 0);
89
90 counter.fetch_sub(n, std::memory_order_acq_rel);
91 }
92
110 void arrive_and_wait(ptrdiff_t n = 1) noexcept
111 {
112 ++num_waiting; // ensure that destructor is not finished in-between the arrive and wait call.
113 arrive(n);
114 wait();
115 --num_waiting;
116 }
117
128 bool try_wait() const noexcept
129 {
130 return counter.load(std::memory_order_acquire) == 0;
131 }
132
148 void wait() const
149 {
150 ++num_waiting; // register waiting thread to synchronise with destructor.
151 spin_delay delay{};
152 while (counter.load(std::memory_order_acquire) > 0)
153 delay.wait();
154 --num_waiting;
155 }
156
157private:
162};
163
164} // namespace seqan3::detail
constexpr std::size_t hardware_destructive_interference_size
Minimum offset between two objects to avoid false sharing.
Definition: new:34
The <new> header from C++17's standard library.
Provides seqan3::detail::spin_delay.