[ovs-dev] [PATCH v3 7/8] lib/ovs-atomic: Native support for x86_64 with GCC.
Jarno Rajahalme
jrajahalme at nicira.com
Fri Aug 1 15:53:11 UTC 2014
Figured this out last night:
On Jul 31, 2014, at 3:21 PM, Jarno Rajahalme <jrajahalme at nicira.com> wrote:
(snip)
> +#define atomic_compare_exchange__(DST, EXP, SRC, RES, CLOB) \
> + asm volatile("lock; cmpxchg %3,%1 ; " \
> + " sete %0 " \
> + "# atomic_compare_exchange__" \
> + : "=q" (RES), /* 0 */ \
> + "+m" (*DST), /* 1 */ \
> + "+a" (EXP) /* 2 */ \
> + : "r" (SRC) /* 3 */ \
> + : CLOB, "cc")
> +
> +/* All memory models are valid for read-modify-write operations.
> + *
> + * Valid memory_models for the read operation of the current value in
“memory models”
> + * the failure case are the same as for atomic read, but can not be
> + * stronger than the success memory model. */
> +#define atomic_compare_exchange_strong_explicit(DST, EXP, SRC, ORDER, ORD_FAIL) \
> + ({ \
> + typeof(DST) dst__ = (DST); \
> + typeof(DST) expp__ = (EXP); \
> + typeof(*DST) src__ = (SRC); \
> + typeof(*DST) exp__ = *expp__; \
> + uint8_t res__; \
> + \
> + if (ORDER > memory_order_consume) { \
> + atomic_compare_exchange__(dst__, exp__, src__, res__, \
> + "memory"); \
> + } else { \
> + atomic_compare_exchange__(dst__, exp__, src__, res__, \
> + "cc"); \
> + } \
> + if (!res__) { \
> + *expp__ = exp__; \
> + atomic_compiler_barrier(ORD_FAIL); \
This barrier is not needed, as the barrier of the atomic_compare_exchange__ is always strong enough. Also the assignment here is not an atomic operation, the atomic load operation was performed by atomic_compare_exchange__, loading the value of *dst__ to exp__ in case of failure. Here we just move the value from one local variable to another; the compiler should have the right to optimize this in any way it likes.
Just to make this clear, this is the breakdown of the different allowed combinations:
ORDER > memory_order_consume: atomic_compare_exchange__ already implements a full CPU & compiler barrier
ORDER == memory_order_acquire: atomic_compare_exchange__ already implements the strongest possible barrier allowed for ORD_FAIL (memory_order_acquire)
ORDER == memory_order_consume: atomic_compare_exchange__ already implements the strongest possible barrier allowed for ORD_FAIL (memory_order_consume)
ORDER == memory_order_relaxed: atomic_compare_exchange__ already implements the strongest possible barrier allowed for ORD_FAIL (memory_order_relaxed)
> + } \
> + (bool)res__; \
> + })
Jarno
More information about the dev
mailing list