[libcxx-commits] [libcxx] [libcxx] Avoid a busy-loop in atomic's lost_wakeup.pass.cpp (PR #211242)

Lucas Chollet via libcxx-commits libcxx-commits at lists.llvm.org
Wed Jul 22 05:05:42 PDT 2026


https://github.com/LucasChollet created https://github.com/llvm/llvm-project/pull/211242

Using __libcpp_thread_poll_with_backoff brings two improvements. First, in case of a lost wake-up, we get an assertion failure instead of a hang. And second, on single-core or heavily loaded systems, the notifier yield instead of burning all its allocated time on the busy-loop.

The measurements were done on my Linux box, the time is the one reported by lit. To isolate the test on a single core I used the following commands:

export LIT_FILTER="wait/lost_wakeup.pass.cpp"
taskset -c 0 ninja -C build check-cxx

| Configuration  | Linux futex |             | Fallback |             |
| -------------- | ----------- | ----------- | -------- | ----------- |
|                | Normal      | Pinned core | Normal   | Pinned core |
| Before         | 1.20s       | 15.54s      | 1.26s    | 601.25s     |
| With backoff   | 1.11s       | 14.42s      | 1.15s    | 17.60s      |

>From f5b7202bb251a1e0f9de9f63da353df40abe26ff Mon Sep 17 00:00:00 2001
From: Lucas Chollet <lucas.chollet at free.fr>
Date: Thu, 9 Jul 2026 16:47:37 +0200
Subject: [PATCH] [libcxx] Avoid a busy-loop in atomic's lost_wakeup.pass.cpp

Using __libcpp_thread_poll_with_backoff brings two improvements. First,
in case of a lost wake-up, we get an assertion failure instead of a
hang. And second, on single-core or heavily loaded systems, the notifier
yield instead of burning all its allocated time on the busy-loop.

The measurements were done on my Linux box, the time is the one reported
by lit. To isolate the test on a single core I used the following
commands:

export LIT_FILTER="wait/lost_wakeup.pass.cpp"
taskset -c 0 ninja -C build check-cxx

| Configuration  | Linux futex |             | Fallback |             |
| -------------- | ----------- | ----------- | -------- | ----------- |
|                | Normal      | Pinned core | Normal   | Pinned core |
| Before         | 1.20s       | 15.54s      | 1.26s    | 601.25s     |
| With backoff   | 1.11s       | 14.42s      | 1.15s    | 17.60s      |
---
 .../atomics.types.operations.wait/lost_wakeup.pass.cpp    | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.wait/lost_wakeup.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.wait/lost_wakeup.pass.cpp
index 17ad72dd74866..6b486173a4743 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.wait/lost_wakeup.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.wait/lost_wakeup.pass.cpp
@@ -14,6 +14,8 @@
 // <atomic>
 
 #include <atomic>
+#include <cassert>
+#include <chrono>
 #include <functional>
 #include <thread>
 #include <vector>
@@ -38,8 +40,10 @@ int main(int, char**) {
 
     auto notify = [&] {
       for (int i = 0; i < num_iterations; ++i) {
-        while (waiter_ready.load() < num_waiters) {
-        }
+        assert(std::__libcpp_thread_poll_with_backoff(
+                   [&]() -> bool { return waiter_ready.load() == num_waiters; },
+                   std::__libcpp_timed_backoff_policy(),
+                   std::chrono::seconds(1)) == std::__poll_with_backoff_results::__poll_success);
         waiter_ready.store(0);
         state.fetch_add(1);
         state.notify_all();



More information about the libcxx-commits mailing list