https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126230

--- Comment #1 from Alexander Krabler <code at a dot krabler.eu> ---
I looked into the code already and, depending on the agreed solution
how to fix this, I may provide a patch for it.

This is caused by the changes introduced for implementing
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0528r3.html,
which requires padding bytes to be ignored for atomic compare-exchange.

Since GCC 13, padding bytes are cleared before every store,
and the atomic compare-exchange expected that all padding bytes
of the atomic value are cleared.
https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=157236dbd621644b3cec50b6cf38811959f3e78c

As atomic_ref can have non-zero padding bytes, retry logic
was added to deal with that in GCC 14.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111077
https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=dcbec954fcba42d97760c6bd98a4c5618473ec93

Basically, when mixing the behavior from GCC <= 12 with the new behavior,
there is no difference between std::atomic<T> and std::atomic_ref<T> regarding
that there could be padding bytes anytime.

Therefore, a possible solution would be to remove the special handling of
std::atomic<T>
inside __compare_exchange.
However, the existing argumentation does not hold for the std::atomic<T> case.

> // compare_exchange is specified to compare value representations.
> // Need to check whether a failure is 'real' or just due to
> // differences in padding bits. This loop should run no more than
> // three times, because the worst case scenario is:
> // First CAS fails because the actual value has non-zero padding.
> // Second CAS fails because another thread stored the same value,
> // but now with padding cleared. Third CAS succeeds.
> // We will never need to loop a fourth time, because any value
> // written by another thread (whether via store, exchange or
> // compare_exchange) will have had its padding cleared.

There could be one thread alternatingly storing the same value with two
different
padding bytes and the other thread trying to execute a compare-exchange.
In theory, this could lead to the compare-exchange(-strong) to never return
or at least there is no upper boundary on the iterations.

I cannot judge, how big that problem is or if this bug is even serious enough
to be
considered to be fixed at all.

Reply via email to