diff mbox

fix generic std::atomic<T>::compare_exchange_{weak,strong}

Message ID 20130726173426.GA11900@cerebro
State New
Headers show

Commit Message

Nathan Froyd July 26, 2013, 5:34 p.m. UTC
Compiling the test program:

#include <atomic>

enum x { a, b };

std::atomic<x> v;

bool test_strong()
{
  x expected = a;
  return v.compare_exchange_strong(expected, b, std::memory_order_acq_rel);
}

bool test_weak()
{
  x expected = a;
  return v.compare_exchange_weak(expected, b, std::memory_order_acq_rel);
}

results in mysterious errors:

In file included from /home/froydnj/mini-atomic-bug.cpp:1:0:
/usr/include/c++/4.7/atomic: In function ‘bool test_strong()’:
/usr/include/c++/4.7/atomic:259:69: error: invalid failure memory model for ‘__atomic_compare_exchange’
/usr/include/c++/4.7/atomic: In function ‘bool test_weak()’:
/usr/include/c++/4.7/atomic:235:68: error: invalid failure memory model for ‘__atomic_compare_exchange’

as the generic std::atomic<T> versions of compare_exchange_strong and
compare_exchange_weak do not call __cmpexch_failure_order.

This patch corrects that oversight.  Tested on x86_64-unknown-linux-gnu.

OK to commit to trunk and active branches?

-Nathan

	* include/std/atomic (compare_exchange_weak, compare_exchange_strong):
	Add call to __cmpexch_failure_order.

Comments

Paolo Carlini July 26, 2013, 5:58 p.m. UTC | #1
Hi,

Nathan Froyd <nfroyd@mozilla.com> ha scritto:
>Compiling the test program:
>
>#include <atomic>
>
>enum x { a, b };
>
>std::atomic<x> v;
>
>bool test_strong()
>{
>  x expected = a;
>return v.compare_exchange_strong(expected, b,
>std::memory_order_acq_rel);
>}
>
>bool test_weak()
>{
>  x expected = a;
>return v.compare_exchange_weak(expected, b, std::memory_order_acq_rel);
>}

In any case, why not adding the testcase?

Paolo
Nathan Froyd July 26, 2013, 6:42 p.m. UTC | #2
Sure, I can do that.  For maximum effectiveness, it'd be good to have it check the specializations for atomic<>, too.  Is there something in the libstdc++ testsuite for iterating template instantiations over a list of types, or do I have to roll the list myself?

Thanks,
-Nathan

----- Original Message -----
> 
> 
> Hi,
> 
> Nathan Froyd <nfroyd@mozilla.com> ha scritto:
> >Compiling the test program:
> >
> >#include <atomic>
> >
> >enum x { a, b };
> >
> >std::atomic<x> v;
> >
> >bool test_strong()
> >{
> >  x expected = a;
> >return v.compare_exchange_strong(expected, b,
> >std::memory_order_acq_rel);
> >}
> >
> >bool test_weak()
> >{
> >  x expected = a;
> >return v.compare_exchange_weak(expected, b, std::memory_order_acq_rel);
> >}
> 
> In any case, why not adding the testcase?
> 
> Paolo
>
Paolo Carlini July 26, 2013, 7:34 p.m. UTC | #3
Hi,

On 07/26/2013 08:42 PM, Nathan Froyd wrote:
> Sure, I can do that.  For maximum effectiveness, it'd be good to have it check the specializations for atomic<>, too.  Is there something in the libstdc++ testsuite for iterating template instantiations over a list of types, or do I have to roll the list myself?
testsuite/29_atomics already uses testsuite_common_types.h

Paolo.
diff mbox

Patch

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index ac2cb45..a822d0f 100644
diff --git a/libstdc++-v3/include/std/atomic b/libstdc++-v3/include/std/atomic
index 813f574..2d66729 100644
--- a/libstdc++-v3/include/std/atomic
+++ b/libstdc++-v3/include/std/atomic
@@ -252,12 +252,14 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       bool
       compare_exchange_weak(_Tp& __e, _Tp __i,
 			    memory_order __m = memory_order_seq_cst) noexcept
-      { return compare_exchange_weak(__e, __i, __m, __m); }
+      { return compare_exchange_weak(__e, __i, __m,
+                                     __cmpexch_failure_order(__m)); }
 
       bool
       compare_exchange_weak(_Tp& __e, _Tp __i,
 		     memory_order __m = memory_order_seq_cst) volatile noexcept
-      { return compare_exchange_weak(__e, __i, __m, __m); }
+      { return compare_exchange_weak(__e, __i, __m,
+                                     __cmpexch_failure_order(__m)); }
 
       bool
       compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s, 
@@ -276,12 +278,14 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       bool
       compare_exchange_strong(_Tp& __e, _Tp __i,
 			       memory_order __m = memory_order_seq_cst) noexcept
-      { return compare_exchange_strong(__e, __i, __m, __m); }
+      { return compare_exchange_strong(__e, __i, __m,
+                                       __cmpexch_failure_order(__m)); }
 
       bool
       compare_exchange_strong(_Tp& __e, _Tp __i,
 		     memory_order __m = memory_order_seq_cst) volatile noexcept
-      { return compare_exchange_strong(__e, __i, __m, __m); }
+      { return compare_exchange_strong(__e, __i, __m,
+                                       __cmpexch_failure_order(__m)); }
     };