4
\$\begingroup\$

Since std::latch is not in many standard C++ libraries, I tried implementing my own, is it OK from memory ordering perspective or yielding?

class Latch {
    std::atomic<unsigned> count;

public:
    explicit Latch(unsigned cnt)
        : count(cnt)
    {
    }

    void arrive_and_wait()
    {
        assert(count > 0);

        count.fetch_sub(1, std::memory_order_release);
        while (count.load(std::memory_order_acquire) > 0) {
            std::this_thread::yield();
        }
    }
};
```
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

First the obvious stuff: the real std::latch::arrive_and_wait is specified to take a ptrdiff_t parameter that defaults to 1, but would also support e.g. myLatch.arrive_and_wait(2). Also, there are more member functions than just arrive_and_wait.

I'd call your thing a "spinlatch" (by analogy to "spinlock"), because it doesn't actually put the thread to sleep — it has an operation named arrive_and_wait that doesn't actually do any waiting! It just keeps loading and loading the atomic variable until it sees zero.

To make it actually wait, you could use the also-new-in-C++20 futex facilities of std::atomic, like this:

void arrive_and_wait(int n = 1) {
    int current = (count -= n);
    if (current == 0) {
        count.notify_all();
    } else {
        while (current != 0) {
            count.wait(current);
            current = count.load();
        }
    }
}

No comment on the memory orders.

\$\endgroup\$
2
  • \$\begingroup\$ Assuming author is talking about std version wihout latch, it's not posible to use C++20 futex you suggest. \$\endgroup\$ Jul 12, 2020 at 23:18
  • \$\begingroup\$ But perhaps condition variables could be used. They are both present in WinAPI and libc of unix \$\endgroup\$ Jul 12, 2020 at 23:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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