>From c4a97d6798619fdb9d97766d1ad7d0553c550a37 Mon Sep 17 00:00:00 2001 Message-Id: From: Tim Blechmann 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