async_latch


An async_latch is the equivalent of the std::latch.

The latch class is a downward counter of type std::ptrdiff_t which can be used to synchronize threads. The value of the counter is initialized on creation. _Coroutines will be suspended_ on the latch until the counter is decremented to zero. There is no possibility to increase or reset the counter, which makes the latch a single-use barrier.

Concurrent invocations of the member functions of latch, except for the destructor, do not introduce data races.

wait_for is an good example for where latches are useful. In particular the ability to use within the same thread multiple times.


Example
async_function<>
your_class::do_work(thread_t _thread, async_latch& _latch)
{
    /* Move into our thread */
    co_await yield(_thread);

    /* Do some pre-work or something... */

    co_await _latch.arrive_and_wait();

    /* Do some work... */
}

async_function<>
your_class::spawn_threads()
{
    const auto threads = engine_->number_of_workers();
    async_latch latch(engine_, threads + 1);

    /* Create worker [logical] threads 0 - n */
    for (std::uint16_t t = 0; t < threads; ++t) {
        do_work(thread_t{t}, latch);
    }

    co_await _latch.arrive_and_wait();

    /* If we get here, all coroutines are in the correct thread  */
    /* and completed their pre-work */
}

class zab::async_latch

Public Functions

inline async_latch(engine *_engine, std::ptrdiff_t _amount)
~async_latch() = default
inline void count_down(std::ptrdiff_t _amount = 1) noexcept
inline bool try_wait() noexcept
inline auto wait() noexcept
inline auto arrive_and_wait(std::ptrdiff_t _amount = 1) noexcept