Program Listing for File latch.hpp¶
↰ Return to documentation for file (include/uitsl/polyfill/latch.hpp)
#pragma once
#ifndef UITSL_POLYFILL_LATCH_HPP_INCLUDE
#define UITSL_POLYFILL_LATCH_HPP_INCLUDE
#include <atomic>
#include <condition_variable>
#include <cstddef>
// polyfill until C++20 barrier becomes available
// TODO C++20 cpp20 switch to std::barrier
// adapted from
// https://github.com/llvm/llvm-project/blob/bcf14f375e29b94e7abb381920df795eeefb2309/libcxx/include/latch
namespace std {
class latch
{
ptrdiff_t arrived;
mutable std::condition_variable cv;
mutable std::mutex mutex;
public:
static constexpr ptrdiff_t max() noexcept {
return std::numeric_limits<ptrdiff_t>::max();
}
inline explicit latch(ptrdiff_t expected)
: arrived(expected)
{ ; }
~latch() = default;
latch(const latch&) = delete;
latch& operator=(const latch&) = delete;
inline void count_down(ptrdiff_t update = 1) {
const std::lock_guard<std::mutex> lock{mutex};
arrived -= update;
if (try_wait()) cv.notify_all();
}
inline bool try_wait() const noexcept { return arrived == 0; }
inline void wait() const {
std::unique_lock<std::mutex> lock(mutex);
cv.wait(lock, [this](){ return try_wait(); });
}
inline void arrive_and_wait(ptrdiff_t update = 1) {
count_down(update);
wait();
}
};
} // namespace uitsl
#endif // #ifndef UITSL_POLYFILL_LATCH_HPP_INCLUDE