>From c4a97d6798619fdb9d97766d1ad7d0553c550a37 Mon Sep 17 00:00:00 2001
Message-Id: <c4a97d6798619fdb9d97766d1ad7d0553c550a37.1355918169.git.tim@klingt.org>
From: Tim Blechmann <tim@klingt.org>
Date: Wed, 19 Dec 2012 12:55:34 +0100
Subject: [PATCH] atomic: x86 - avoid duplicate memory barriers on cmpxchg
 instructions

---
 boost/atomic/detail/gcc-x86.hpp |  121 ++++++++++++++++-----------------------
 1 file changed, 49 insertions(+), 72 deletions(-)

diff --git a/boost/atomic/detail/gcc-x86.hpp b/boost/atomic/detail/gcc-x86.hpp
index 5c30320..9d3791b 100644
--- a/boost/atomic/detail/gcc-x86.hpp
+++ b/boost/atomic/detail/gcc-x86.hpp
@@ -308,17 +308,15 @@ public:
         memory_order failure_order) volatile
     {
         value_type previous = expected;
-        platform_fence_before(success_order);
-        __asm__ (
+
+        // acts as full memory barrier
+        __asm__ __volatile__(
             "lock ; cmpxchgb %2, %1"
             : "+a" (previous), "+m" (v_)
             : "q" (desired)
+            : "memory"
         );
         bool success = (previous == expected);
-        if (success)
-            platform_fence_after(success_order);
-        else
-            platform_fence_after(failure_order);
         expected = previous;
         return success;
     }
@@ -436,17 +434,15 @@ public:
         memory_order failure_order) volatile
     {
         value_type previous = expected;
-        platform_fence_before(success_order);
-        __asm__ (
+
+        // acts as full memory barrier
+        __asm__ __volatile__(
             "lock ; cmpxchgw %2, %1"
             : "+a" (previous), "+m" (v_)
             : "q" (desired)
+            : "memory"
         );
         bool success = (previous == expected);
-        if (success)
-            platform_fence_after(success_order);
-        else
-            platform_fence_after(failure_order);
         expected = previous;
         return success;
     }
@@ -564,17 +560,15 @@ public:
         memory_order failure_order) volatile
     {
         value_type previous = expected;
-        platform_fence_before(success_order);
-        __asm__ (
+
+        // acts as full memory barrier
+        __asm__ __volatile__(
             "lock ; cmpxchgl %2, %1"
             : "+a" (previous), "+m" (v_)
             : "r" (desired)
+            : "memory"
         );
         bool success = (previous == expected);
-        if (success)
-            platform_fence_after(success_order);
-        else
-            platform_fence_after(failure_order);
         expected = previous;
         return success;
     }
@@ -693,17 +687,15 @@ public:
         memory_order failure_order) volatile
     {
         value_type previous = expected;
-        platform_fence_before(success_order);
-        __asm__ (
+
+        // acts as full memory barrier
+        __asm__ __volatile__(
             "lock ; cmpxchgq %2, %1"
             : "+a" (previous), "+m" (v_)
             : "r" (desired)
+            : "memory"
         );
         bool success = (previous == expected);
-        if (success)
-            platform_fence_after(success_order);
-        else
-            platform_fence_after(failure_order);
         expected = previous;
         return success;
     }
@@ -803,17 +795,15 @@ public:
         memory_order failure_order) volatile
     {
         value_type previous = expected;
-        platform_fence_before(success_order);
-        __asm__ (
+
+        // acts as full memory barrier
+        __asm__ __volatile__(
             "lock ; cmpxchgl %2, %1"
             : "+a" (previous), "+m" (v_)
             : "r" (desired)
+            : "memory"
         );
         bool success = (previous == expected);
-        if (success)
-            platform_fence_after(success_order);
-        else
-            platform_fence_after(failure_order);
         expected = previous;
         return success;
     }
@@ -886,17 +876,15 @@ public:
         memory_order failure_order) volatile
     {
         value_type previous = expected;
-        platform_fence_before(success_order);
-        __asm__ (
+
+        // acts as full memory barrier
+        __asm__ __volatile__ (
             "lock ; cmpxchgl %2, %1"
             : "+a" (previous), "+m" (v_)
             : "r" (desired)
+            : "memory"
         );
         bool success = (previous == expected);
-        if (success)
-            platform_fence_after(success_order);
-        else
-            platform_fence_after(failure_order);
         expected = previous;
         return success;
     }
@@ -987,17 +975,15 @@ public:
         memory_order failure_order) volatile
     {
         value_type previous = expected;
-        platform_fence_before(success_order);
-        __asm__ (
+
+        // acts as full memory barrier
+        __asm__ __volatile__(
             "lock ; cmpxchgq %2, %1"
             : "+a" (previous), "+m" (v_)
             : "r" (desired)
+            : "memory"
         );
         bool success = (previous == expected);
-        if (success)
-            platform_fence_after(success_order);
-        else
-            platform_fence_after(failure_order);
         expected = previous;
         return success;
     }
@@ -1070,17 +1056,15 @@ public:
         memory_order failure_order) volatile
     {
         value_type previous = expected;
-        platform_fence_before(success_order);
-        __asm__ (
+
+        // acts as full memory barrier
+        __asm__ __volatile__(
             "lock ; cmpxchgq %2, %1"
             : "+a" (previous), "+m" (v_)
             : "r" (desired)
+            : "memory"
         );
         bool success = (previous == expected);
-        if (success)
-            platform_fence_after(success_order);
-        else
-            platform_fence_after(failure_order);
         expected = previous;
         return success;
     }
@@ -1191,17 +1175,16 @@ public:
         memcpy(&expected_s, &expected, sizeof(value_type));
         memcpy(&desired_s, &desired, sizeof(value_type));
         storage_type previous_s = expected_s;
-        platform_fence_before(success_order);
-        __asm__ (
+
+        // acts as full memory barrier
+        __asm__ __volatile__ (
             "lock ; cmpxchgb %2, %1"
             : "+a" (previous_s), "+m" (v_)
             : "q" (desired_s)
+            : "memory"
         );
         bool success = (previous_s == expected_s);
-        if (success)
-            platform_fence_after(success_order);
-        else
-            platform_fence_after(failure_order);
+
         memcpy(&expected, &previous_s, sizeof(value_type));
         return success;
     }
@@ -1291,17 +1274,15 @@ public:
         memcpy(&expected_s, &expected, sizeof(value_type));
         memcpy(&desired_s, &desired, sizeof(value_type));
         storage_type previous_s = expected_s;
-        platform_fence_before(success_order);
-        __asm__ (
+
+        // acts as full memory barrier
+        __asm__ __volatile__(
             "lock ; cmpxchgw %2, %1"
             : "+a" (previous_s), "+m" (v_)
             : "q" (desired_s)
+            : "memory"
         );
         bool success = (previous_s == expected_s);
-        if (success)
-            platform_fence_after(success_order);
-        else
-            platform_fence_after(failure_order);
         memcpy(&expected, &previous_s, sizeof(value_type));
         return success;
     }
@@ -1391,17 +1372,15 @@ public:
         memcpy(&expected_s, &expected, sizeof(value_type));
         memcpy(&desired_s, &desired, sizeof(value_type));
         storage_type previous_s = expected_s;
-        platform_fence_before(success_order);
-        __asm__ (
+
+        // acts as full memory barrier
+        __asm__ __volatile__ (
             "lock ; cmpxchgl %2, %1"
             : "+a" (previous_s), "+m" (v_)
             : "q" (desired_s)
+            : "memory"
         );
         bool success = (previous_s == expected_s);
-        if (success)
-            platform_fence_after(success_order);
-        else
-            platform_fence_after(failure_order);
         memcpy(&expected, &previous_s, sizeof(value_type));
         return success;
     }
@@ -1492,17 +1471,15 @@ public:
         memcpy(&expected_s, &expected, sizeof(value_type));
         memcpy(&desired_s, &desired, sizeof(value_type));
         storage_type previous_s = expected_s;
-        platform_fence_before(success_order);
-        __asm__ (
+
+        // acts as full memory barrier
+        __asm__ __volatile__(
             "lock ; cmpxchgq %2, %1"
             : "+a" (previous_s), "+m" (v_)
             : "q" (desired_s)
+            : "memory"
         );
         bool success = (previous_s == expected_s);
-        if (success)
-            platform_fence_after(success_order);
-        else
-            platform_fence_after(failure_order);
         memcpy(&expected, &previous_s, sizeof(value_type));
         return success;
     }
-- 
1.7.10.4

