SeqAn3 3.4.0-rc.1
The Modern C++ library for sequence analysis.
|
A single-use synchronisation point for closable concurrent data structures. More...
#include <seqan3/utility/parallel/detail/reader_writer_manager.hpp>
Classes | |
class | scoped_reader_type |
A strictly scope-based seqan3::detail::reader_writer_manager wrapper for consumer threads. More... | |
class | scoped_writer_type |
A strictly scope-based seqan3::detail::reader_writer_manager wrapper for producer threads. More... | |
Public Member Functions | |
void | reader_arrive () noexcept |
Atomically decrements reader counter by one. | |
void | reader_arrive_and_wait () noexcept |
Atomically decrements writer counter by one and blocks the calling thread. | |
scoped_reader_type | register_reader () noexcept |
Registers the current thread as a consumer thread for the monitored resource. | |
scoped_writer_type | register_writer () noexcept |
Registers the current thread as a producer thread for the monitored resource. | |
void | writer_arrive () noexcept |
Atomically decrements writer counter by one. | |
void | writer_arrive_and_wait () noexcept |
Atomically decrements writer counter by one and blocks the calling thread. | |
Constructors, destructor and assignment | |
reader_writer_manager ()=delete | |
Deleted. | |
reader_writer_manager (reader_writer_manager const &)=delete | |
Deleted. | |
reader_writer_manager (reader_writer_manager &&)=delete | |
Deleted. | |
reader_writer_manager & | operator= (reader_writer_manager const &)=delete |
Deleted. | |
reader_writer_manager & | operator= (reader_writer_manager &&)=delete |
Deleted. | |
~reader_writer_manager ()=default | |
Defaulted. | |
template<typename concurrent_t > requires requires { std::declval<concurrent_t>().close(); } | |
reader_writer_manager (reader_count const rcount, writer_count const wcount, concurrent_t &ds) | |
Constructs the reader_writer_manager with the reader count, writer count and the associated data structure. | |
Private Attributes | |
std::function< void()> | completion_fn |
The stored completion function. | |
std::once_flag | flag |
This flag ensures that the completion phase is invoked only once. | |
latch | reader_latch |
The internal latch for consumer threads. | |
latch | writer_latch |
The internal latch for producer threads. | |
A single-use synchronisation point for closable concurrent data structures.
A reader writer manager is a thread coordination mechanism specifically designed to synchronise with a concurrent data structure such as the seqan3::detail::buffer_queue. In particular, the manager is constructed with a seqan3::detail::reader_count and a seqan3::detail::writer_count and offers special functions for readers and writers that arrive at the synchronisation point. If all writers arrived at the synchronisation point the associated concurrent data structure is closed by invoking the member method close()
. This so called completion phase is triggered by only one of the participating producer threads. Accordingly, no more data can be added to the concurrent data structure and possibly waiting readers on an empty data structure can be released. The destructor of the reader_writer_manager will wait until all readers and writers arrived at the synchronisation point. Thus, a concurrent data structure can be safely destructed after the reader_writer_manager is destructed.
The class offers functions to register participating producer and consumer threads, which will signal if they are done when their destructor is called.
The reader_writer_manager class is neither copyable nor movable due to internal members used for inter thread synchronisation. Accordingly, the class is not default constructible.
|
inline |
Constructs the reader_writer_manager with the reader count, writer count and the associated data structure.
concurrent_t | The type of the concurrent data structure. Must have a member function close . |
rcount | The expected number of consumer threads. Must be at least one. |
wcount | The expected number of producer threads. Must be at least one. |
ds | The concurrent data structure. |
Initialises a std::contrib::latch for the consumer threads and a std::contrib::latch for the producer threads. Initialises the completion function which calls ds.close()
on completion. Note, only a reference to the concurrent data structure is stored. The caller must ensure that ds
is not destructed before this.
Throws std::invalid_argument if reader count or writer count is less than 1.
|
inlinenoexcept |
Atomically decrements reader counter by one.
Arrives at the synchronisation point for consumer threads without blocking the calling thread.
Guaranteed not to throw.
Thread-safe.
|
inlinenoexcept |
Atomically decrements writer counter by one and blocks the calling thread.
Arrives at the synchronisation point for consumer threads and blocks the calling thread until all participating threads have arrived.
Guaranteed not to throw.
Thread-safe.
|
inlinenoexcept |
Registers the current thread as a consumer thread for the monitored resource.
If a thread calls this function it will become a participating consumer thread for the monitored concurrent data structure. On destruction of the returned RAII wrapper class seqan3::detail::reader_writer_manager::reader_arrive is called automatically.
Guaranteed not to throw.
Thread-safe.
|
inlinenoexcept |
Registers the current thread as a producer thread for the monitored resource.
If a thread calls this function it will become a participating producer thread for the monitored concurrent data structure. On destruction of the returned RAII wrapper class seqan3::detail::reader_writer_manager::writer_arrive is called automatically.
Guaranteed not to throw.
Thread-safe.
|
inlinenoexcept |
Atomically decrements writer counter by one.
Arrives at the synchronisation point for producer threads without blocking the calling thread. If all participating producer threads arrived at the synchronisation point, one of the threads will invoke the completion function.
Guaranteed not to throw.
Thread-safe.
|
inlinenoexcept |
Atomically decrements writer counter by one and blocks the calling thread.
Arrives at the synchronisation point for producer threads and blocks the calling thread until all participating threads have arrived. If all participating producer threads arrived at the synchronisation point, one of the threads will invoke the completion function.
Guaranteed not to throw.
Thread-safe.