Skip to content

Commit

Permalink
libstdc++: Remove "no stronger" assertion in compare exchange [PR102177]
Browse files Browse the repository at this point in the history
P0418R2 removed some preconditions from std::atomic::compare_exchange_*
but we still enforce them via __glibcxx_assert. This removes those
assertions.

Signed-off-by: Jonathan Wakely <jwakely@redhat.com>

libstdc++-v3/ChangeLog:

	PR c++/102177
	* include/bits/atomic_base.h (__is_valid_cmpexch_failure_order):
	New function to check if a memory order is valid for the failure
	case of compare exchange operations.
	(__atomic_base<I>::compare_exchange_weak): Simplify assertions
	by using __is_valid_cmpexch_failure_order.
	(__atomic_base<I>::compare_exchange_strong): Likewise.
	(__atomic_base<P*>::compare_exchange_weak): Likewise.
	(__atomic_base<P*>::compare_exchange_strong): Likewise.
	(__atomic_impl::compare_exchange_weak): Add assertion.
	(__atomic_impl::compare_exchange_strong): Likewise.
	* include/std/atomic (atomic::compare_exchange_weak): Likewise.
	(atomic::compare_exchange_strong): Likewise.
  • Loading branch information
jwakely committed Sep 2, 2021
1 parent 5b73abd commit dba1ab2
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 44 deletions.
61 changes: 17 additions & 44 deletions libstdc++-v3/include/bits/atomic_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
| __memory_order_modifier(__m & __memory_order_modifier_mask));
}

constexpr bool
__is_valid_cmpexch_failure_order(memory_order __m) noexcept
{
return (__m & __memory_order_mask) != memory_order_release
&& (__m & __memory_order_mask) != memory_order_acq_rel;
}

_GLIBCXX_ALWAYS_INLINE void
atomic_thread_fence(memory_order __m) noexcept
{ __atomic_thread_fence(int(__m)); }
Expand Down Expand Up @@ -511,13 +518,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
compare_exchange_weak(__int_type& __i1, __int_type __i2,
memory_order __m1, memory_order __m2) noexcept
{
memory_order __b2 __attribute__ ((__unused__))
= __m2 & __memory_order_mask;
memory_order __b1 __attribute__ ((__unused__))
= __m1 & __memory_order_mask;
__glibcxx_assert(__b2 != memory_order_release);
__glibcxx_assert(__b2 != memory_order_acq_rel);
__glibcxx_assert(__b2 <= __b1);
__glibcxx_assert(__is_valid_cmpexch_failure_order(__m2));

return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 1,
int(__m1), int(__m2));
Expand All @@ -528,13 +529,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
memory_order __m1,
memory_order __m2) volatile noexcept
{
memory_order __b2 __attribute__ ((__unused__))
= __m2 & __memory_order_mask;
memory_order __b1 __attribute__ ((__unused__))
= __m1 & __memory_order_mask;
__glibcxx_assert(__b2 != memory_order_release);
__glibcxx_assert(__b2 != memory_order_acq_rel);
__glibcxx_assert(__b2 <= __b1);
__glibcxx_assert(__is_valid_cmpexch_failure_order(__m2));

return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 1,
int(__m1), int(__m2));
Expand All @@ -560,13 +555,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
compare_exchange_strong(__int_type& __i1, __int_type __i2,
memory_order __m1, memory_order __m2) noexcept
{
memory_order __b2 __attribute__ ((__unused__))
= __m2 & __memory_order_mask;
memory_order __b1 __attribute__ ((__unused__))
= __m1 & __memory_order_mask;
__glibcxx_assert(__b2 != memory_order_release);
__glibcxx_assert(__b2 != memory_order_acq_rel);
__glibcxx_assert(__b2 <= __b1);
__glibcxx_assert(__is_valid_cmpexch_failure_order(__m2));

return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 0,
int(__m1), int(__m2));
Expand All @@ -577,14 +566,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
memory_order __m1,
memory_order __m2) volatile noexcept
{
memory_order __b2 __attribute__ ((__unused__))
= __m2 & __memory_order_mask;
memory_order __b1 __attribute__ ((__unused__))
= __m1 & __memory_order_mask;

__glibcxx_assert(__b2 != memory_order_release);
__glibcxx_assert(__b2 != memory_order_acq_rel);
__glibcxx_assert(__b2 <= __b1);
__glibcxx_assert(__is_valid_cmpexch_failure_order(__m2));

return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 0,
int(__m1), int(__m2));
Expand Down Expand Up @@ -869,13 +851,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
memory_order __m1,
memory_order __m2) noexcept
{
memory_order __b2 __attribute__ ((__unused__))
= __m2 & __memory_order_mask;
memory_order __b1 __attribute__ ((__unused__))
= __m1 & __memory_order_mask;
__glibcxx_assert(__b2 != memory_order_release);
__glibcxx_assert(__b2 != memory_order_acq_rel);
__glibcxx_assert(__b2 <= __b1);
__glibcxx_assert(__is_valid_cmpexch_failure_order(__m2));

return __atomic_compare_exchange_n(&_M_p, &__p1, __p2, 0,
int(__m1), int(__m2));
Expand All @@ -886,14 +862,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
memory_order __m1,
memory_order __m2) volatile noexcept
{
memory_order __b2 __attribute__ ((__unused__))
= __m2 & __memory_order_mask;
memory_order __b1 __attribute__ ((__unused__))
= __m1 & __memory_order_mask;

__glibcxx_assert(__b2 != memory_order_release);
__glibcxx_assert(__b2 != memory_order_acq_rel);
__glibcxx_assert(__b2 <= __b1);
__glibcxx_assert(__is_valid_cmpexch_failure_order(__m2));

return __atomic_compare_exchange_n(&_M_p, &__p1, __p2, 0,
int(__m1), int(__m2));
Expand Down Expand Up @@ -996,6 +965,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_Val<_Tp> __desired, memory_order __success,
memory_order __failure) noexcept
{
__glibcxx_assert(__is_valid_cmpexch_failure_order(__failure));

return __atomic_compare_exchange(__ptr, std::__addressof(__expected),
std::__addressof(__desired), true,
int(__success), int(__failure));
Expand All @@ -1007,6 +978,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_Val<_Tp> __desired, memory_order __success,
memory_order __failure) noexcept
{
__glibcxx_assert(__is_valid_cmpexch_failure_order(__failure));

return __atomic_compare_exchange(__ptr, std::__addressof(__expected),
std::__addressof(__desired), false,
int(__success), int(__failure));
Expand Down
8 changes: 8 additions & 0 deletions libstdc++-v3/include/std/atomic
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s,
memory_order __f) noexcept
{
__glibcxx_assert(__is_valid_cmpexch_failure_order(__f));

return __atomic_compare_exchange(std::__addressof(_M_i),
std::__addressof(__e),
std::__addressof(__i),
Expand All @@ -330,6 +332,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s,
memory_order __f) volatile noexcept
{
__glibcxx_assert(__is_valid_cmpexch_failure_order(__f));

return __atomic_compare_exchange(std::__addressof(_M_i),
std::__addressof(__e),
std::__addressof(__i),
Expand All @@ -352,6 +356,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s,
memory_order __f) noexcept
{
__glibcxx_assert(__is_valid_cmpexch_failure_order(__f));

return __atomic_compare_exchange(std::__addressof(_M_i),
std::__addressof(__e),
std::__addressof(__i),
Expand All @@ -362,6 +368,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s,
memory_order __f) volatile noexcept
{
__glibcxx_assert(__is_valid_cmpexch_failure_order(__f));

return __atomic_compare_exchange(std::__addressof(_M_i),
std::__addressof(__e),
std::__addressof(__i),
Expand Down

0 comments on commit dba1ab2

Please sign in to comment.