2
0
mirror of https://github.com/boostorg/atomic.git synced 2026-02-09 10:22:20 +00:00

Fixed compilation of ARM backend. Simplified fences implementation.

This commit is contained in:
Andrey Semashev
2014-05-11 14:18:49 +04:00
parent 684917a6fe
commit c196e6da0c
7 changed files with 91 additions and 303 deletions

View File

@@ -92,28 +92,14 @@ struct gcc_arm_operations_base
{
static BOOST_FORCEINLINE void fence_before(memory_order order) BOOST_NOEXCEPT
{
switch (order)
{
case memory_order_release:
case memory_order_acq_rel:
case memory_order_seq_cst:
if ((order & memory_order_release) != 0)
hardware_full_fence();
break;
default:;
}
}
static BOOST_FORCEINLINE void fence_after(memory_order order) BOOST_NOEXCEPT
{
switch (order)
{
case memory_order_acquire:
case memory_order_acq_rel:
case memory_order_seq_cst:
if ((order & memory_order_acquire) != 0)
hardware_full_fence();
break;
default:;
}
}
static BOOST_FORCEINLINE void fence_after_store(memory_order order) BOOST_NOEXCEPT
@@ -278,7 +264,7 @@ struct operations< 4u, Signed > :
[result] "=&r" (result), // %1
[tmp] "=&l" (tmp), // %2
[storage] "+Q" (storage) // %3
: [value] "r" (v), // %4
: [value] "r" (v) // %4
: "cc"
);
fence_after(order);
@@ -304,7 +290,7 @@ struct operations< 4u, Signed > :
[result] "=&r" (result), // %1
[tmp] "=&l" (tmp), // %2
[storage] "+Q" (storage) // %3
: [value] "r" (v), // %4
: [value] "r" (v) // %4
: "cc"
);
fence_after(order);
@@ -330,7 +316,7 @@ struct operations< 4u, Signed > :
[result] "=&r" (result), // %1
[tmp] "=&l" (tmp), // %2
[storage] "+Q" (storage) // %3
: [value] "r" (v), // %4
: [value] "r" (v) // %4
: "cc"
);
fence_after(order);
@@ -356,7 +342,7 @@ struct operations< 4u, Signed > :
[result] "=&r" (result), // %1
[tmp] "=&l" (tmp), // %2
[storage] "+Q" (storage) // %3
: [value] "r" (v), // %4
: [value] "r" (v) // %4
: "cc"
);
fence_after(order);
@@ -382,7 +368,7 @@ struct operations< 4u, Signed > :
[result] "=&r" (result), // %1
[tmp] "=&l" (tmp), // %2
[storage] "+Q" (storage) // %3
: [value] "r" (v), // %4
: [value] "r" (v) // %4
: "cc"
);
fence_after(order);
@@ -433,7 +419,7 @@ struct operations< 1u, false > :
[result] "=&r" (result), // %1
[tmp] "=&l" (tmp), // %2
[storage] "+Q" (storage) // %3
: [value] "r" (v), // %4
: [value] "r" (v) // %4
: "cc"
);
fence_after(order);
@@ -460,7 +446,7 @@ struct operations< 1u, false > :
[result] "=&r" (result), // %1
[tmp] "=&l" (tmp), // %2
[storage] "+Q" (storage) // %3
: [value] "r" (v), // %4
: [value] "r" (v) // %4
: "cc"
);
fence_after(order);
@@ -495,7 +481,7 @@ struct operations< 1u, true > :
[result] "=&r" (result), // %1
[tmp] "=&l" (tmp), // %2
[storage] "+Q" (storage) // %3
: [value] "r" (v), // %4
: [value] "r" (v) // %4
: "cc"
);
fence_after(order);
@@ -522,7 +508,7 @@ struct operations< 1u, true > :
[result] "=&r" (result), // %1
[tmp] "=&l" (tmp), // %2
[storage] "+Q" (storage) // %3
: [value] "r" (v), // %4
: [value] "r" (v) // %4
: "cc"
);
fence_after(order);
@@ -558,7 +544,7 @@ struct operations< 2u, false > :
[result] "=&r" (result), // %1
[tmp] "=&l" (tmp), // %2
[storage] "+Q" (storage) // %3
: [value] "r" (v), // %4
: [value] "r" (v) // %4
: "cc"
);
fence_after(order);
@@ -585,7 +571,7 @@ struct operations< 2u, false > :
[result] "=&r" (result), // %1
[tmp] "=&l" (tmp), // %2
[storage] "+Q" (storage) // %3
: [value] "r" (v), // %4
: [value] "r" (v) // %4
: "cc"
);
fence_after(order);
@@ -620,7 +606,7 @@ struct operations< 2u, true > :
[result] "=&r" (result), // %1
[tmp] "=&l" (tmp), // %2
[storage] "+Q" (storage) // %3
: [value] "r" (v), // %4
: [value] "r" (v) // %4
: "cc"
);
fence_after(order);
@@ -647,7 +633,7 @@ struct operations< 2u, true > :
[result] "=&r" (result), // %1
[tmp] "=&l" (tmp), // %2
[storage] "+Q" (storage) // %3
: [value] "r" (v), // %4
: [value] "r" (v) // %4
: "cc"
);
fence_after(order);
@@ -671,7 +657,7 @@ struct operations< 2u, true > :
template< bool Signed >
struct operations< 8u, Signed > :
public gcc_ppc_operations_base
public gcc_arm_operations_base
{
typedef typename make_storage_type< 8u, Signed >::type storage_type;
@@ -690,7 +676,7 @@ struct operations< 8u, Signed > :
"ldrexd %1, %H1, %2\n"
BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0)
: "=&l" (tmp), // %0
"=&r" (original), // %1
"=&r" (original) // %1
: "Q" (storage) // %2
);
fence_after(order);
@@ -815,7 +801,7 @@ struct operations< 8u, Signed > :
"=&r" (result), // %1
"=&l" (tmp), // %2
"+Q" (storage) // %3
: "r" (v), // %4
: "r" (v) // %4
: "cc"
);
fence_after(order);
@@ -842,7 +828,7 @@ struct operations< 8u, Signed > :
"=&r" (result), // %1
"=&l" (tmp), // %2
"+Q" (storage) // %3
: "r" (v), // %4
: "r" (v) // %4
: "cc"
);
fence_after(order);
@@ -869,7 +855,7 @@ struct operations< 8u, Signed > :
"=&r" (result), // %1
"=&l" (tmp), // %2
"+Q" (storage) // %3
: "r" (v), // %4
: "r" (v) // %4
: "cc"
);
fence_after(order);
@@ -896,7 +882,7 @@ struct operations< 8u, Signed > :
"=&r" (result), // %1
"=&l" (tmp), // %2
"+Q" (storage) // %3
: "r" (v), // %4
: "r" (v) // %4
: "cc"
);
fence_after(order);
@@ -923,7 +909,7 @@ struct operations< 8u, Signed > :
"=&r" (result), // %1
"=&l" (tmp), // %2
"+Q" (storage) // %3
: "r" (v), // %4
: "r" (v) // %4
: "cc"
);
fence_after(order);
@@ -951,30 +937,14 @@ struct operations< 8u, Signed > :
BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT
{
switch (order)
{
case memory_order_acquire:
case memory_order_release:
case memory_order_acq_rel:
case memory_order_seq_cst:
if ((order & (memory_order_acquire | memory_order_release)) != 0)
gcc_arm_operations_base::hardware_full_fence();
break;
default:;
}
}
BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT
{
switch (order)
{
case memory_order_acquire:
case memory_order_release:
case memory_order_acq_rel:
case memory_order_seq_cst:
if ((order & ~memory_order_consume) != 0)
__asm__ __volatile__ ("" ::: "memory");
break;
default:;
}
}
} // namespace detail

View File

@@ -77,38 +77,29 @@ struct gcc_ppc_operations_base
{
static BOOST_FORCEINLINE void fence_before(memory_order order) BOOST_NOEXCEPT
{
switch (order)
{
case memory_order_release:
case memory_order_acq_rel:
#if defined(__powerpc64__)
__asm__ __volatile__ ("lwsync" ::: "memory");
break;
#endif
case memory_order_seq_cst:
if (order == memory_order_seq_cst)
__asm__ __volatile__ ("sync" ::: "memory");
default:;
}
else if ((order & memory_order_release) != 0)
__asm__ __volatile__ ("lwsync" ::: "memory");
#else
if ((order & memory_order_release) != 0)
__asm__ __volatile__ ("sync" ::: "memory");
#endif
}
static BOOST_FORCEINLINE void fence_after(memory_order order) BOOST_NOEXCEPT
{
switch (order)
{
case memory_order_acquire:
case memory_order_acq_rel:
case memory_order_seq_cst:
__asm__ __volatile__ ("isync");
case memory_order_consume:
if ((order & memory_order_acquire) != 0)
__asm__ __volatile__ ("isync" ::: "memory");
else if (order == memory_order_consume)
__asm__ __volatile__ ("" ::: "memory");
default:;
}
}
static BOOST_FORCEINLINE void fence_after_store(memory_order order) BOOST_NOEXCEPT
{
if (order == memory_order_seq_cst)
__asm__ __volatile__ ("sync");
__asm__ __volatile__ ("sync" ::: "memory");
}
};
@@ -766,16 +757,8 @@ BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT
BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT
{
switch (order)
{
case memory_order_acquire:
case memory_order_release:
case memory_order_acq_rel:
case memory_order_seq_cst:
if ((order & ~memory_order_consume) != 0)
__asm__ __volatile__ ("" ::: "memory");
break;
default:;
}
}
} // namespace detail

View File

@@ -36,39 +36,18 @@ struct gcc_sparc_cas_base
{
static BOOST_FORCEINLINE void fence_before(memory_order order) BOOST_NOEXCEPT
{
switch (order)
{
case memory_order_relaxed:
case memory_order_acquire:
case memory_order_consume:
break;
case memory_order_release:
case memory_order_acq_rel:
__asm__ __volatile__ ("membar #StoreStore | #LoadStore" ::: "memory");
break;
case memory_order_seq_cst:
if (order == memory_order_seq_cst)
__asm__ __volatile__ ("membar #Sync" ::: "memory");
break;
}
else if ((order & memory_order_release) != 0)
__asm__ __volatile__ ("membar #StoreStore | #LoadStore" ::: "memory");
}
static BOOST_FORCEINLINE void fence_after(memory_order order) BOOST_NOEXCEPT
{
switch (order)
{
case memory_order_relaxed:
case memory_order_consume:
case memory_order_release:
break;
case memory_order_acquire:
case memory_order_acq_rel:
__asm__ __volatile__ ("membar #LoadLoad | #LoadStore" ::: "memory");
break;
case memory_order_seq_cst:
if (order == memory_order_seq_cst)
__asm__ __volatile__ ("membar #Sync" ::: "memory");
break;
default:;
}
else if ((order & memory_order_acquire) != 0)
__asm__ __volatile__ ("membar #StoreStore | #LoadStore" ::: "memory");
}
static BOOST_FORCEINLINE void fence_after_store(memory_order order) BOOST_NOEXCEPT
@@ -76,11 +55,6 @@ struct gcc_sparc_cas_base
if (order == memory_order_seq_cst)
__asm__ __volatile__ ("membar #Sync" ::: "memory");
}
static BOOST_FORCEINLINE void fence_after_load(memory_order order) BOOST_NOEXCEPT
{
fence_after(order);
}
};
template< bool Signed >
@@ -99,7 +73,7 @@ struct gcc_sparc_cas32 :
static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT
{
storage_type v = storage;
fence_after_load(order);
fence_after(order);
return v;
}
@@ -191,7 +165,7 @@ struct gcc_sparc_cas64 :
static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT
{
storage_type v = storage;
fence_after_load(order);
fence_after(order);
return v;
}
@@ -237,10 +211,8 @@ struct operations< 8u, Signed > :
BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT
{
switch(order)
switch (order)
{
case memory_order_relaxed:
break;
case memory_order_release:
__asm__ __volatile__ ("membar #StoreStore | #LoadStore" ::: "memory");
break;
@@ -250,18 +222,20 @@ BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT
case memory_order_acq_rel:
__asm__ __volatile__ ("membar #LoadLoad | #LoadStore | #StoreStore" ::: "memory");
break;
case memory_order_consume:
break;
case memory_order_seq_cst:
__asm__ __volatile__ ("membar #Sync" ::: "memory");
break;
default:;
case memory_order_consume:
case memory_order_relaxed:
default:
break;
}
}
BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT
{
__asm__ __volatile__ ("" ::: "memory");
if ((order & ~memory_order_consume) != 0)
__asm__ __volatile__ ("" ::: "memory");
}
} // namespace detail

View File

@@ -31,8 +31,30 @@ namespace boost {
namespace atomics {
namespace detail {
struct gcc_sync_operations_base
{
static BOOST_FORCEINLINE void fence_before_store(memory_order order) BOOST_NOEXCEPT
{
if ((order & memory_order_release) != 0)
__sync_synchronize();
}
static BOOST_FORCEINLINE void fence_after_store(memory_order order) BOOST_NOEXCEPT
{
if (order == memory_order_seq_cst)
__sync_synchronize();
}
static BOOST_FORCEINLINE void fence_after_load(memory_order order) BOOST_NOEXCEPT
{
if ((order & (memory_order_acquire | memory_order_consume)) != 0)
__sync_synchronize();
}
};
template< typename T >
struct gcc_sync_operations
struct gcc_sync_operations :
public gcc_sync_operations_base
{
typedef T storage_type;
@@ -126,45 +148,6 @@ struct gcc_sync_operations
{
return true;
}
private:
static BOOST_FORCEINLINE void fence_before_store(memory_order order) BOOST_NOEXCEPT
{
switch (order)
{
case memory_order_relaxed:
case memory_order_acquire:
case memory_order_consume:
break;
case memory_order_release:
case memory_order_acq_rel:
case memory_order_seq_cst:
__sync_synchronize();
break;
}
}
static BOOST_FORCEINLINE void fence_after_store(memory_order order) BOOST_NOEXCEPT
{
if (order == memory_order_seq_cst)
__sync_synchronize();
}
static BOOST_FORCEINLINE void fence_after_load(memory_order order) BOOST_NOEXCEPT
{
switch (order)
{
case memory_order_relaxed:
case memory_order_release:
break;
case memory_order_consume:
case memory_order_acquire:
case memory_order_acq_rel:
case memory_order_seq_cst:
__sync_synchronize();
break;
}
}
};
#if BOOST_ATOMIC_INT8_LOCK_FREE > 0
@@ -237,35 +220,14 @@ struct operations< 16u, Signed > :
BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT
{
switch (order)
{
case memory_order_relaxed:
break;
case memory_order_release:
case memory_order_consume:
case memory_order_acquire:
case memory_order_acq_rel:
case memory_order_seq_cst:
if (order != memory_order_relaxed)
__sync_synchronize();
break;
}
}
BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT
{
switch (order)
{
case memory_order_relaxed:
case memory_order_consume:
break;
case memory_order_acquire:
case memory_order_release:
case memory_order_acq_rel:
case memory_order_seq_cst:
if ((order & ~memory_order_consume) != 0)
__asm__ __volatile__ ("" ::: "memory");
break;
default:;
}
}
} // namespace detail

View File

@@ -44,61 +44,14 @@ struct gcc_x86_operations_base
{
static BOOST_FORCEINLINE void fence_before(memory_order order) BOOST_NOEXCEPT
{
switch (order)
{
case memory_order_relaxed:
case memory_order_acquire:
case memory_order_consume:
break;
case memory_order_release:
case memory_order_acq_rel:
if ((order & memory_order_release) != 0)
__asm__ __volatile__ ("" ::: "memory");
break;
case memory_order_seq_cst:
__asm__ __volatile__ ("" ::: "memory");
break;
default:;
}
}
static BOOST_FORCEINLINE void fence_after(memory_order order) BOOST_NOEXCEPT
{
switch (order)
{
case memory_order_relaxed:
case memory_order_release:
break;
case memory_order_acquire:
case memory_order_acq_rel:
if ((order & memory_order_acquire) != 0)
__asm__ __volatile__ ("" ::: "memory");
break;
case memory_order_consume:
break;
case memory_order_seq_cst:
__asm__ __volatile__ ("" ::: "memory");
break;
default:;
}
}
static BOOST_FORCEINLINE void fence_after_load(memory_order order) BOOST_NOEXCEPT
{
switch (order)
{
case memory_order_relaxed:
case memory_order_release:
break;
case memory_order_acquire:
case memory_order_acq_rel:
__asm__ __volatile__ ("" ::: "memory");
break;
case memory_order_consume:
break;
case memory_order_seq_cst:
__asm__ __volatile__ ("" ::: "memory");
break;
default:;
}
}
};
@@ -125,7 +78,7 @@ struct gcc_x86_operations :
static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT
{
storage_type v = storage;
fence_after_load(order);
fence_after(order);
return v;
}
@@ -750,17 +703,8 @@ struct operations< 16u, Signed > :
BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT
{
switch (order)
if (order == memory_order_seq_cst)
{
case memory_order_relaxed:
case memory_order_consume:
break;
case memory_order_acquire:
case memory_order_release:
case memory_order_acq_rel:
__asm__ __volatile__ ("" ::: "memory");
break;
case memory_order_seq_cst:
__asm__ __volatile__
(
#if defined(__x86_64__) || defined(__SSE2__)
@@ -770,26 +714,17 @@ BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT
#endif
::: "memory"
);
break;
default:;
}
else if ((order & (memory_order_acquire | memory_order_release)) != 0)
{
__asm__ __volatile__ ("" ::: "memory");
}
}
BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT
{
switch (order)
{
case memory_order_relaxed:
case memory_order_consume:
break;
case memory_order_acquire:
case memory_order_release:
case memory_order_acq_rel:
case memory_order_seq_cst:
if ((order & ~memory_order_consume) != 0)
__asm__ __volatile__ ("" ::: "memory");
break;
default:;
}
}
} // namespace detail

View File

@@ -59,16 +59,8 @@ struct linux_arm_cas_base
{
static BOOST_FORCEINLINE void fence_before_store(memory_order order) BOOST_NOEXCEPT
{
switch (order)
{
case memory_order_release:
case memory_order_acq_rel:
case memory_order_seq_cst:
if ((order & memory_order_release) != 0)
hardware_full_fence();
break;
case memory_order_consume:
default:;
}
}
static BOOST_FORCEINLINE void fence_after_store(memory_order order) BOOST_NOEXCEPT
@@ -79,15 +71,8 @@ struct linux_arm_cas_base
static BOOST_FORCEINLINE void fence_after_load(memory_order order) BOOST_NOEXCEPT
{
switch (order)
{
case memory_order_acquire:
case memory_order_acq_rel:
case memory_order_seq_cst:
if ((order & memory_order_acquire) != 0)
hardware_full_fence();
break;
default:;
}
}
static BOOST_FORCEINLINE void hardware_full_fence() BOOST_NOEXCEPT
@@ -175,35 +160,14 @@ struct operations< 4u, Signed > :
BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT
{
switch (order)
{
case memory_order_relaxed:
break;
case memory_order_release:
case memory_order_consume:
case memory_order_acquire:
case memory_order_acq_rel:
case memory_order_seq_cst:
if ((order & (memory_order_acquire | memory_order_release)) != 0)
linux_arm_cas_base::hardware_full_fence();
break;
}
}
BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT
{
switch (order)
{
case memory_order_relaxed:
case memory_order_consume:
break;
case memory_order_acquire:
case memory_order_release:
case memory_order_acq_rel:
case memory_order_seq_cst:
if ((order & ~memory_order_consume) != 0)
__asm__ __volatile__ ("" ::: "memory");
break;
default:;
}
}
} // namespace detail

View File

@@ -25,13 +25,13 @@
#define BOOST_ATOMIC_DETAIL_PLATFORM emulated
#define BOOST_ATOMIC_EMULATED
/*
// Intel compiler does not support __atomic* intrinsics properly, although defines them (tested with 13.0.1 and 13.1.1 on Linux)
#elif (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 407) && !defined(BOOST_INTEL_CXX_VERSION))\
|| (defined(BOOST_CLANG) && ((__clang_major__ * 100 + __clang_minor__) >= 302))
#define BOOST_ATOMIC_DETAIL_PLATFORM gcc_atomic
*/
#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
#define BOOST_ATOMIC_DETAIL_PLATFORM gcc_x86