[all-commits] [llvm/llvm-project] 208a6d: [libc++] Fix inconsistency between is_lock_free an...
Louis Dionne via All-commits
all-commits at lists.llvm.org
Wed Oct 18 19:58:37 PDT 2023
Branch: refs/heads/main
Home: https://github.com/llvm/llvm-project
Commit: 208a6d97f56fc36da6833a0e14e5847b7d84322e
https://github.com/llvm/llvm-project/commit/208a6d97f56fc36da6833a0e14e5847b7d84322e
Author: Louis Dionne <ldionne.2 at gmail.com>
Date: 2023-10-18 (Wed, 18 Oct 2023)
Changed paths:
M libcxx/include/__atomic/atomic_base.h
M libcxx/test/libcxx/atomics/atomics.align/align.pass.cpp
M libcxx/test/std/atomics/atomics.lockfree/isalwayslockfree.pass.cpp
M libcxx/test/std/atomics/atomics.types.generic/address.pass.cpp
M libcxx/test/std/atomics/atomics.types.generic/bool.pass.cpp
M libcxx/test/std/atomics/atomics.types.generic/integral.pass.cpp
M libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_is_lock_free.pass.cpp
Log Message:
-----------
[libc++] Fix inconsistency between is_lock_free and is_always_lock_free (#68109)
std::atomic is implemented with the following (confusing!) hierarchy of
types:
std::atomic<T> : std::__atomic_base<T> { ... };
std::__atomic_base<T> {
std::__cxx_atomic_impl<T> __impl;
};
std::__cxx_atomic_impl<T> {
_Atomic(T) __val;
};
Inside std::__atomic_base, we implement the is_lock_free() and
is_always_lock_free() functions. However, we used to implement them
inconsistently:
- is_always_lock_free() is based on whether __cxx_atomic_impl<T> is
always lock free (using the builtin), which means that we include any
potential padding added by _Atomic(T) into the determination.
- is_lock_free() was based on whether T is lock free (using the
builtin), which meant that we did not take into account any potential
padding added by _Atomic(T).
It is important to note that the padding added by _Atomic(T) can turn a
type that wouldn't be lock free into a lock free type, for example by
making its size become a power of two.
The inconsistency of how the two functions were implemented could lead
to cases where is_always_lock_free() would return true, but
is_lock_free() would then return false. This is the case for example of
the following type, which is always lock free on arm64 but was
incorrectly reported as !is_lock_free() before this patch:
struct Foo { float x[3]; };
This patch switches the determination of is_lock_free() to be based on
__cxx_atomic_impl<T> instead to match how we determine
is_always_lock_free().
rdar://115324353
More information about the All-commits
mailing list