[libcxx-commits] [libcxx] [libc++][test] atomit wait test take 2 (PR #169206)

via libcxx-commits libcxx-commits at lists.llvm.org
Sat Dec 6 23:51:21 PST 2025


https://github.com/huixie90 updated https://github.com/llvm/llvm-project/pull/169206

>From bf78bf3d839bbcb4a6555e32bbc150ef4371cbf4 Mon Sep 17 00:00:00 2001
From: Hui Xie <hui.xie1990 at gmail.com>
Date: Sat, 22 Nov 2025 17:37:22 +0000
Subject: [PATCH 1/5] [libc++] test for atomic::wait

---
 .../lost_wakeup.pass.cpp                      | 58 +++++++++++++++++++
 1 file changed, 58 insertions(+)
 create mode 100644 libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.wait/lost_wakeup.pass.cpp

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
new file mode 100644
index 0000000000000..5a0d587815828
--- /dev/null
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.wait/lost_wakeup.pass.cpp
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: no-threads
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// This is a stress test for std::atomic::wait for lost wake ups.
+
+// <atomic>
+
+#include <atomic>
+#include <functional>
+#include <thread>
+#include <vector>
+
+#include "make_test_thread.h"
+
+constexpr int num_waiters    = 8;
+constexpr int num_iterations = 10'000;
+
+int main(int, char**) {
+  for (int run = 0; run < 20; ++run) {
+    std::atomic<int> waiter_ready(0);
+    std::atomic<int> state(0);
+
+    auto wait = [&]() {
+      for (int i = 0; i < num_iterations; ++i) {
+        auto old_state = state.load(std::memory_order_acquire);
+        waiter_ready.fetch_add(1, std::memory_order_acq_rel);
+        state.wait(old_state, std::memory_order_acquire);
+      }
+    };
+
+    auto notify = [&] {
+      for (int i = 0; i < num_iterations; ++i) {
+        while (waiter_ready.load(std::memory_order_acquire) < num_waiters) {
+          std::this_thread::yield();
+        }
+        waiter_ready.store(0, std::memory_order_release);
+        state.fetch_add(1, std::memory_order_acq_rel);
+        state.notify_all();
+      }
+    };
+
+    std::vector<std::jthread> threads;
+    for (int i = 0; i < num_waiters; ++i)
+      threads.push_back(support::make_test_jthread(wait));
+
+    threads.push_back(support::make_test_jthread(notify));
+  }
+
+  return 0;
+}

>From 020f47f84a5711208379e83626a5f31af0576d8f Mon Sep 17 00:00:00 2001
From: Hui Xie <hui.xie1990 at gmail.com>
Date: Sun, 23 Nov 2025 09:36:57 +0000
Subject: [PATCH 2/5] seq_cst

---
 .../lost_wakeup.pass.cpp                             | 12 ++++++------
 1 file changed, 6 insertions(+), 6 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 5a0d587815828..fc96ea1a8f201 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
@@ -30,19 +30,19 @@ int main(int, char**) {
 
     auto wait = [&]() {
       for (int i = 0; i < num_iterations; ++i) {
-        auto old_state = state.load(std::memory_order_acquire);
-        waiter_ready.fetch_add(1, std::memory_order_acq_rel);
-        state.wait(old_state, std::memory_order_acquire);
+        auto old_state = state.load();
+        waiter_ready.fetch_add(1);
+        state.wait(old_state);
       }
     };
 
     auto notify = [&] {
       for (int i = 0; i < num_iterations; ++i) {
-        while (waiter_ready.load(std::memory_order_acquire) < num_waiters) {
+        while (waiter_ready.load() < num_waiters) {
           std::this_thread::yield();
         }
-        waiter_ready.store(0, std::memory_order_release);
-        state.fetch_add(1, std::memory_order_acq_rel);
+        waiter_ready.store(0);
+        state.fetch_add(1);
         state.notify_all();
       }
     };

>From 0beef0957d43a5fa93276a5a2910ddc2724c08c9 Mon Sep 17 00:00:00 2001
From: Hui Xie <hui.xie1990 at gmail.com>
Date: Sat, 6 Dec 2025 15:13:59 +0000
Subject: [PATCH 3/5] remove yield and add debug

---
 .../atomics.types.operations.wait/lost_wakeup.pass.cpp     | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

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 fc96ea1a8f201..293d2f94fb93a 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
@@ -17,6 +17,7 @@
 #include <functional>
 #include <thread>
 #include <vector>
+#include <iostream>
 
 #include "make_test_thread.h"
 
@@ -25,6 +26,7 @@ constexpr int num_iterations = 10'000;
 
 int main(int, char**) {
   for (int run = 0; run < 20; ++run) {
+    std::cerr << "run " << run << std::endl;
     std::atomic<int> waiter_ready(0);
     std::atomic<int> state(0);
 
@@ -38,8 +40,11 @@ int main(int, char**) {
 
     auto notify = [&] {
       for (int i = 0; i < num_iterations; ++i) {
+        if (i % 1000 == 0)
+          std::cerr << "run " << run << "  notify iteration " << i << std::endl;
+
         while (waiter_ready.load() < num_waiters) {
-          std::this_thread::yield();
+        //  std::this_thread::yield();
         }
         waiter_ready.store(0);
         state.fetch_add(1);

>From eb741e996ff88c401c729a8275ae1f87b85e68a6 Mon Sep 17 00:00:00 2001
From: Hui Xie <hui.xie1990 at gmail.com>
Date: Sat, 6 Dec 2025 21:13:06 +0000
Subject: [PATCH 4/5] test

---
 .../atomics.types.operations.wait/lost_wakeup.pass.cpp          | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

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 293d2f94fb93a..a16271835f626 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
@@ -44,7 +44,7 @@ int main(int, char**) {
           std::cerr << "run " << run << "  notify iteration " << i << std::endl;
 
         while (waiter_ready.load() < num_waiters) {
-        //  std::this_thread::yield();
+          std::this_thread::yield();
         }
         waiter_ready.store(0);
         state.fetch_add(1);

>From 380e26389dbed4575d672c2153073ea0b42f0cef Mon Sep 17 00:00:00 2001
From: Hui Xie <hui.xie1990 at gmail.com>
Date: Sun, 7 Dec 2025 07:51:09 +0000
Subject: [PATCH 5/5] more debug

---
 .../atomics.types.operations.wait/lost_wakeup.pass.cpp   | 9 +++++++--
 1 file changed, 7 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 a16271835f626..7d5f1929566de 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,10 +14,12 @@
 // <atomic>
 
 #include <atomic>
+#include <chrono>
 #include <functional>
 #include <thread>
 #include <vector>
 #include <iostream>
+#include <iomanip>
 
 #include "make_test_thread.h"
 
@@ -25,6 +27,7 @@ constexpr int num_waiters    = 8;
 constexpr int num_iterations = 10'000;
 
 int main(int, char**) {
+  auto start = std::chrono::high_resolution_clock::now();
   for (int run = 0; run < 20; ++run) {
     std::cerr << "run " << run << std::endl;
     std::atomic<int> waiter_ready(0);
@@ -41,7 +44,9 @@ int main(int, char**) {
     auto notify = [&] {
       for (int i = 0; i < num_iterations; ++i) {
         if (i % 1000 == 0)
-          std::cerr << "run " << run << "  notify iteration " << i << std::endl;
+          std::cerr << std::fixed << std::setprecision(2) << std::left
+                    << std::chrono::duration<double>(std::chrono::high_resolution_clock::now() - start) << " run "
+                    << run << "  notify iteration " << i << std::endl;
 
         while (waiter_ready.load() < num_waiters) {
           std::this_thread::yield();
@@ -59,5 +64,5 @@ int main(int, char**) {
     threads.push_back(support::make_test_jthread(notify));
   }
 
-  return 0;
+  return 1;
 }



More information about the libcxx-commits mailing list