Skip to content

<atomic>: On x64, atomic_ref::is_lock_free() incorrectly returns true when it shouldn't #4728

Description

Repros with VS 2022 17.11 Preview 2 x64:

C:\Temp>type meow.cpp
#include <atomic>
#include <print>
using namespace std;

struct Large {
    char str[100]{};
};

int main() {
    Large lg{};
    atomic_ref<Large> atom_ref{lg};
    println("atomic_ref<Large> is_lock_free(): {}", atom_ref.is_lock_free());
    atom_ref.store(Large{"cute fluffy kittens"});
    println("lg.str: {}", lg.str);
}
C:\Temp>cl /EHsc /nologo /W4 /std:c++latest /MTd /Od /Zi /Fdmeow.pdb meow.cpp
meow.cpp

C:\Temp>meow
atomic_ref<Large> is_lock_free(): true
lg.str: cute fluffy kittens

atomic_ref<Large>::store() definitely takes a lock:

STL/stl/inc/atomic

Lines 630 to 635 in e36ee6c

void store(const _TVal _Value, const memory_order _Order = memory_order_seq_cst) noexcept {
// store with sequential consistency
_Check_store_memory_order(_Order);
_Guard _Lock{_Spinlock};
_Storage = _Value;
}

atomic_ref::is_lock_free() is bogus because:

STL/stl/inc/atomic

Lines 2367 to 2376 in e36ee6c

_NODISCARD bool is_lock_free() const noexcept {
#if _ATOMIC_HAS_DCAS
return is_always_lock_free;
#else // ^^^ _ATOMIC_HAS_DCAS / !_ATOMIC_HAS_DCAS vvv
if constexpr (is_always_lock_free) {
return true;
} else {
return __std_atomic_has_cmpxchg16b() != 0;
}
#endif // ^^^ !_ATOMIC_HAS_DCAS ^^^

This meant to say: "If we're always lock-free then true, otherwise we have to be potentially lock-free and actually have cmpxchg16b."

I have a fix.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingfixedSomething works now, yay!

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions