[libc++][test] Use loop with compare_exchange_weak calls (#185953)

On AIX, this test sometimes fails with error `Assertion failed: y ==
true`. The test assumes `compare_exchange_weak` should succeed on a
single call, however according to the standard:

> A weak compare-and-exchange operation may fail spuriously. That is,
even when the contents of memory referred to by expected and ptr are
equal, it may return false and store back to expected the same memory
contents that were originally there.
This spurious failure enables implementation of compare-and-exchange on
a broader class of machines, e.g., load-locked store-conditional
machines. A consequence of spurious failure is that nearly all uses of
weak compare-and-exchange will be in a loop.

[atomics.ref.ops]/27
This commit is contained in:
Jake Egan 2026-03-14 22:34:48 -04:00 committed by GitHub
parent 044776691a
commit 3fea2f6165
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -33,11 +33,11 @@ struct TestCompareExchangeWeak {
std::atomic_ref<T> const a(x);
T t(T(1));
std::same_as<bool> decltype(auto) y = a.compare_exchange_weak(t, T(2));
assert(y == true);
while (!a.compare_exchange_weak(t, T(2))) {
}
assert(a == T(2));
assert(t == T(1));
y = a.compare_exchange_weak(t, T(3));
std::same_as<bool> decltype(auto) y = a.compare_exchange_weak(t, T(3));
assert(y == false);
assert(a == T(2));
assert(t == T(2));
@ -49,11 +49,11 @@ struct TestCompareExchangeWeak {
std::atomic_ref<T> const a(x);
T t(T(1));
std::same_as<bool> decltype(auto) y = a.compare_exchange_weak(t, T(2), std::memory_order_seq_cst);
assert(y == true);
while (!a.compare_exchange_weak(t, T(2), std::memory_order_seq_cst)) {
}
assert(a == T(2));
assert(t == T(1));
y = a.compare_exchange_weak(t, T(3), std::memory_order_seq_cst);
std::same_as<bool> decltype(auto) y = a.compare_exchange_weak(t, T(3), std::memory_order_seq_cst);
assert(y == false);
assert(a == T(2));
assert(t == T(2));
@ -65,12 +65,12 @@ struct TestCompareExchangeWeak {
std::atomic_ref<T> const a(x);
T t(T(1));
std::same_as<bool> decltype(auto) y =
a.compare_exchange_weak(t, T(2), std::memory_order_release, std::memory_order_relaxed);
assert(y == true);
while (!a.compare_exchange_weak(t, T(2), std::memory_order_release, std::memory_order_relaxed)) {
}
assert(a == T(2));
assert(t == T(1));
y = a.compare_exchange_weak(t, T(3), std::memory_order_release, std::memory_order_relaxed);
std::same_as<bool> decltype(auto) y =
a.compare_exchange_weak(t, T(3), std::memory_order_release, std::memory_order_relaxed);
assert(y == false);
assert(a == T(2));
assert(t == T(2));