QAtomic: pass explicit failure memory order to std::atomic::compare_exchange_strong
GCC 4.8 seems to get the failure memory order wrong when using the overload that only accepts one memory order and produces errors such as: bits/atomic_base.h:577:70: error: failure memory model cannot be stronger than success memory model for '__atomic_compare_exchange' return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 0, __m1, __m2); ^ (as seen on Android). Fix by explicitly passing the failure orders corresponding to the success orders, as specified by the standard: relaxed → relaxed release → relaxed acquire → acquire acq_rel → acquire (cf. http://en.cppreference.com/w/cpp/atomic/atomic/compare_exchange). Task-number: QTBUG-59399 Change-Id: If046e735888cf331d2d6506d8d5ca9aa7402f9ad Reviewed-by: David Faure <david.faure@kdab.com> Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
This commit is contained in:
parent
9ed389bf15
commit
5cc0de2e08
@ -278,7 +278,7 @@ template <typename X> struct QAtomicOps
|
||||
template <typename T>
|
||||
static bool testAndSetRelaxed(std::atomic<T> &_q_value, T expectedValue, T newValue, T *currentValue = Q_NULLPTR) Q_DECL_NOTHROW
|
||||
{
|
||||
bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_relaxed);
|
||||
bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_relaxed, std::memory_order_relaxed);
|
||||
if (currentValue)
|
||||
*currentValue = expectedValue;
|
||||
return tmp;
|
||||
@ -287,7 +287,7 @@ template <typename X> struct QAtomicOps
|
||||
template <typename T>
|
||||
static bool testAndSetAcquire(std::atomic<T> &_q_value, T expectedValue, T newValue, T *currentValue = Q_NULLPTR) Q_DECL_NOTHROW
|
||||
{
|
||||
bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_acquire);
|
||||
bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_acquire, std::memory_order_acquire);
|
||||
if (currentValue)
|
||||
*currentValue = expectedValue;
|
||||
return tmp;
|
||||
@ -296,7 +296,7 @@ template <typename X> struct QAtomicOps
|
||||
template <typename T>
|
||||
static bool testAndSetRelease(std::atomic<T> &_q_value, T expectedValue, T newValue, T *currentValue = Q_NULLPTR) Q_DECL_NOTHROW
|
||||
{
|
||||
bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_release);
|
||||
bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_release, std::memory_order_relaxed);
|
||||
if (currentValue)
|
||||
*currentValue = expectedValue;
|
||||
return tmp;
|
||||
@ -305,7 +305,7 @@ template <typename X> struct QAtomicOps
|
||||
template <typename T>
|
||||
static bool testAndSetOrdered(std::atomic<T> &_q_value, T expectedValue, T newValue, T *currentValue = Q_NULLPTR) Q_DECL_NOTHROW
|
||||
{
|
||||
bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_acq_rel);
|
||||
bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_acq_rel, std::memory_order_acquire);
|
||||
if (currentValue)
|
||||
*currentValue = expectedValue;
|
||||
return tmp;
|
||||
|
Loading…
Reference in New Issue
Block a user