[libcxx-commits] [clang] [libcxx] [clang] Add builtin to clear padding bytes (prework for P0528R3) (PR #75371)
via libcxx-commits
libcxx-commits at lists.llvm.org
Sat Apr 25 03:36:44 PDT 2026
huixie90 wrote:
> Can you describe the algorithm for `compare_exchange` for `atomic_ref` that handles the case where the in-memory padding is not zero and how that algorithm uses this intrinsic?
```
bool valueRepresentationEquals(T x, T y) {
clear_padding(&x);
clear_padding(&y);
return memcmp(&x, &y, sizeof(T));
}
bool atomic_ref<T>::compareExchange(T& expected, T desired) {
T expectedCopy = expected;
clear_padding(&expectedCopy);
clear_padding(&desired);
T oldExepected = expectedCopy;
bool r1 = CAS(&get(), &expectedCopy, desired);
if (r1) return true;
if (!valueRepresentationEquals(oldExepected, expectedCopy)) {
// value representation of expected changed, it is true CAS fail
memcpy(&expected, &expectedCopy, sizeof(T));
return false;
}
// the CAS failed due to some padding difference
// at this point, expectedCopy should have the original's atomic_ref's padding
T oldExepected2 = expectedCopy;
bool r2 = CAS(&get(), &expectedCopy, desired);
if (r1) {
// if the atomic_ref wasn't changed since the first CAS, it should go to this branch
return true;
}
// atomic_ref has changed between the first and second CAS
// atomic_ref's owning padding must be zeroed already because all writes to atomic_ref cleared the padding
if (!valueRepresentationEquals(oldExepected2, expectedCopy)) {
// value representation of expected changed, it is true CAS fail
memcpy(&expected, &expectedCopy, sizeof(T));
return false;
}
// so the second CAS failed due to padding difference (the oldExepected2 has original atomic_ref's padding but atomic_ref's padding being zeroed by other writes
// expectedCopy has been updated again to have the updated atomic_ref, which has zeros in their paddings
// at this point, both expectedCopy and atomic_ref must have zeroed paddings
bool r3 = CAS(&get(), &expectedCopy, desired);
if (!r3) memcpy(&expected, &expectedCopy, sizeof(T));
return r3;
}
```
The code surely can be simplied but you get the idea. @gonzalobg
https://github.com/llvm/llvm-project/pull/75371
More information about the libcxx-commits
mailing list