As an exercise to learn more about multi-threading and atomic operations work in C++, I decided to implement a latch class in C++11 loosely based off of std::latch class from C++20 and would like to know whether this implementation is flawed in any sort of way or form and how I could improve upon it:

#include <cstdint>
#include <atomic>
#include <mutex>

class latch {
    std::atomic<std::ptrdiff_t> counter_;
    mutable std::mutex mut_;

    explicit latch(std::ptrdiff_t const def = 1) : counter_(def) {}

    void count_down(std::ptrdiff_t const n = 1) {
        counter_ -= n;

    void wait() const {
        if (!counter_.load(std::memory_order_relaxed)) return;
        std::lock_guard<std::mutex> lock(mut_);
        while (counter_.load(std::memory_order_relaxed));

    bool try_wait() const noexcept {
        return !counter_.load(std::memory_order_relaxed);

    void arrive_and_wait(std::ptrdiff_t const n = 1) {

I also tried to test it out and it appears to work just fine.


The only thing missing that's present in std::latch is the max constant. We can easily add that:

static constexpr std::ptrdiff_t max() noexcept
    return std::numeric_limits<std::ptrdiff_t>::max();

I think that wait() is flawed: the first thread to get here (taking the mutex) will busy-loop (while). Really, we should wait on a condition variable so that we're not consuming resources while the other threads are still progressing.

  • \$\begingroup\$ Taking what you said into consideration, would this be correct way to do it then? \$\endgroup\$
    – noes
    Oct 24 '21 at 18:30
  • \$\begingroup\$ I think so - perhaps worth posting that as a follow-on question - link back to this one to help give context if you like. \$\endgroup\$ Oct 24 '21 at 18:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.