libstdc++-v3/
authorfroydnj <froydnj@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 29 Jul 2013 17:13:05 +0000 (17:13 +0000)
committerfroydnj <froydnj@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 29 Jul 2013 17:13:05 +0000 (17:13 +0000)
* include/std/atomic (compare_exchange_weak, compare_exchange_strong):
Add call to __cmpexch_failure_order.
* testsuite/util/testsuite_common_types.h
(compare_exchange_order_lowering): New generator.
* testsuite/29_atomics/atomic/requirements/compare_exchange_lowering.cc:
New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@201315 138bc75d-0d04-0410-961f-82ee72b054a4

libstdc++-v3/ChangeLog
libstdc++-v3/include/std/atomic
libstdc++-v3/testsuite/29_atomics/atomic/requirements/compare_exchange_lowering.cc [new file with mode: 0644]
libstdc++-v3/testsuite/util/testsuite_common_types.h

index d0a494b..edb17ea 100644 (file)
@@ -1,3 +1,12 @@
+2013-07-29  Nathan Froyd  <froydnj@gcc.gnu.org>
+
+       * include/std/atomic (compare_exchange_weak, compare_exchange_strong):
+       Add call to __cmpexch_failure_order.
+       * testsuite/util/testsuite_common_types.h
+       (compare_exchange_order_lowering): New generator.
+       * testsuite/29_atomics/atomic/requirements/compare_exchange_lowering.cc:
+       New test.
+
 2013-07-25  Paolo Carlini  <paolo.carlini@oracle.com>
 
        * include/std/complex (pow(const complex<>&, int)): Enable in
index 813f574..2d66729 100644 (file)
@@ -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)); }
     };
 
 
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic/requirements/compare_exchange_lowering.cc b/libstdc++-v3/testsuite/29_atomics/atomic/requirements/compare_exchange_lowering.cc
new file mode 100644 (file)
index 0000000..7e5d58f
--- /dev/null
@@ -0,0 +1,65 @@
+// { dg-options "-std=gnu++11" }
+// { dg-do compile }
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <atomic>
+#include <testsuite_common_types.h>
+
+#define TEST_ALL_ORDERS()                       \
+  do {                                          \
+    ORDER_TEST(std::memory_order_relaxed);      \
+    ORDER_TEST(std::memory_order_consume);      \
+    ORDER_TEST(std::memory_order_acquire);      \
+    ORDER_TEST(std::memory_order_release);      \
+    ORDER_TEST(std::memory_order_acq_rel);      \
+    ORDER_TEST(std::memory_order_seq_cst);      \
+  } while(0)
+  
+void test01()
+{
+#define ORDER_TEST(ORDER)                                               \
+  do {                                                                  \
+    __gnu_test::compare_exchange_order_lowering<ORDER> test;            \
+    __gnu_cxx::typelist::apply_generator(test,                          \
+                                         __gnu_test::integral_types::type()); \
+  } while (0);
+  TEST_ALL_ORDERS();
+#undef ORDER_TEST
+
+  enum e { a, b, c };
+#define ORDER_TEST(ORDER)                               \
+  do {                                                  \
+    std::atomic<e> x(a);                                \
+    e expected = a;                                     \
+    x.compare_exchange_strong(expected, b, ORDER);      \
+    x.compare_exchange_weak(expected, c, ORDER);        \
+  } while (0);
+  TEST_ALL_ORDERS();
+#undef ORDER_TEST
+
+#define ORDER_TEST(ORDER)                       \
+  do {                                          \
+    std::atomic<void*> x(nullptr);              \
+    void* expected = nullptr;                   \
+    x.compare_exchange_strong(expected, nullptr, ORDER);        \
+    x.compare_exchange_weak(expected, nullptr, ORDER);          \
+  } while (0);
+  TEST_ALL_ORDERS();
+#undef ORDER_TEST
+}
index 54d6a75..12e3921 100644 (file)
@@ -872,5 +872,22 @@ namespace __gnu_test
          = &_Concept::__constraint;
       }
   };
+
+#if __cplusplus >= 201103L
+  // Generator to test lowering requirements for compare-and-exchange.
+  template<std::memory_order _Torder>
+  struct compare_exchange_order_lowering
+  {
+    template<typename _Tp>
+      void
+      operator()()
+      {
+        std::atomic<_Tp> __x;
+        _Tp __expected = 0;
+        __x.compare_exchange_strong(__expected, 1, _Torder);
+        __x.compare_exchange_weak(__expected, 1, _Torder);
+      }
+  };
+#endif
 } // namespace __gnu_test
 #endif