Thanks to visit codestin.com
Credit goes to github.com

Skip to content

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

@StephanTLavavej

Description

@StephanTLavavej

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.

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