From: Jonathan Wakely Date: Thu, 9 Jan 2025 22:03:15 +0000 (+0000) Subject: libstdc++: Optimise std::latch::arrive_and_wait X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=88e41d761e02f77345ad88b42500e2ef3861c245;p=thirdparty%2Fgcc.git libstdc++: Optimise std::latch::arrive_and_wait We don't need to wait if we know the counter has reached zero. libstdc++-v3/ChangeLog: * include/std/latch (latch::arrive_and_wait): Optimise. --- diff --git a/libstdc++-v3/include/std/latch b/libstdc++-v3/include/std/latch index 52a2b1489f6..9504df0a722 100644 --- a/libstdc++-v3/include/std/latch +++ b/libstdc++-v3/include/std/latch @@ -101,8 +101,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_ALWAYS_INLINE void arrive_and_wait(ptrdiff_t __update = 1) noexcept { - count_down(__update); - wait(); + // The standard specifies this functions as count_down(update); wait(); + // but we combine those two calls into one and avoid the wait() if we + // know the counter reached zero. + + __glibcxx_assert(__update >= 0 && __update <= max()); + // Use acq_rel here because an omitted wait() would have used acquire: + auto const __old = __atomic_impl::fetch_sub(&_M_counter, __update, + memory_order::acq_rel); + if (std::cmp_equal(__old, __update)) + __atomic_impl::notify_all(&_M_counter); + else + { + __glibcxx_assert(std::cmp_less(__update, __old)); + wait(); + } } private: