diff --git a/opal/include/opal/sys/amd64/atomic.h b/opal/include/opal/sys/amd64/atomic.h index cf8d099bad..39cc3f0c4f 100644 --- a/opal/include/opal/sys/amd64/atomic.h +++ b/opal/include/opal/sys/amd64/atomic.h @@ -44,6 +44,10 @@ #define OPAL_HAVE_ATOMIC_CMPSET_64 1 +#define OPAL_HAVE_ATOMIC_SWAP_32 1 + +#define OPAL_HAVE_ATOMIC_SWAP_64 1 + /********************************************************************** * * Memory Barriers @@ -119,6 +123,40 @@ static inline int opal_atomic_cmpset_64( volatile int64_t *addr, #define opal_atomic_cmpset_acq_64 opal_atomic_cmpset_64 #define opal_atomic_cmpset_rel_64 opal_atomic_cmpset_64 +#if OMPI_GCC_INLINE_ASSEMBLY + +static inline int32_t opal_atomic_swap_32( volatile int32_t *addr, + int32_t newval) +{ + int32_t oldval; + + __asm__ __volatile__("xchg %0, %1" : + "=r" (oldval), "=m" (*addr) : + "0" (newval), "m" (*addr) : + "memory"); + return oldval; +} + +#endif /* OMPI_GCC_INLINE_ASSEMBLY */ + +#if OMPI_GCC_INLINE_ASSEMBLY + +static inline int64_t opal_atomic_swap_64( volatile int64_t *addr, + int64_t newval) +{ + int64_t oldval; + + __asm__ __volatile__("xchgq %1, %0" : + "=r" (oldval) : + "m" (*addr), "0" (newval) : + "memory"); + return oldval; +} + +#endif /* OMPI_GCC_INLINE_ASSEMBLY */ + + + #if OMPI_GCC_INLINE_ASSEMBLY #define OPAL_HAVE_ATOMIC_MATH_32 1 diff --git a/opal/include/opal/sys/atomic.h b/opal/include/opal/sys/atomic.h index 4911f0c259..01e83668d3 100644 --- a/opal/include/opal/sys/atomic.h +++ b/opal/include/opal/sys/atomic.h @@ -121,6 +121,8 @@ typedef struct opal_atomic_lock_t opal_atomic_lock_t; #define OPAL_HAVE_INLINE_ATOMIC_SUB_32 0 #define OPAL_HAVE_INLINE_ATOMIC_ADD_64 0 #define OPAL_HAVE_INLINE_ATOMIC_SUB_64 0 +#define OPAL_HAVE_INLINE_ATOMIC_SWAP_32 0 +#define OPAL_HAVE_INLINE_ATOMIC_SWAP_64 0 #else #define OPAL_HAVE_INLINE_ATOMIC_MEM_BARRIER 1 #define OPAL_HAVE_INLINE_ATOMIC_CMPSET_32 1 @@ -129,6 +131,8 @@ typedef struct opal_atomic_lock_t opal_atomic_lock_t; #define OPAL_HAVE_INLINE_ATOMIC_SUB_32 1 #define OPAL_HAVE_INLINE_ATOMIC_ADD_64 1 #define OPAL_HAVE_INLINE_ATOMIC_SUB_64 1 +#define OPAL_HAVE_INLINE_ATOMIC_SWAP_32 1 +#define OPAL_HAVE_INLINE_ATOMIC_SWAP_64 1 #endif /********************************************************************** @@ -561,6 +565,16 @@ static inline int opal_atomic_cmpset_rel_ptr(volatile void* addr, #endif /* (OPAL_HAVE_ATOMIC_CMPSET_32 || OPAL_HAVE_ATOMIC_CMPSET_64) */ +#if defined(DOXYGEN) || (OPAL_HAVE_ATOMIC_SWAP_32 || OPAL_HAVE_ATOMIC_SWAP_64) + +#if SIZEOF_VOID_P == 4 && OPAL_HAVE_ATOMIC_SWAP_32 +#define opal_atomic_swap_ptr(addr, value) opal_atomic_swap_32((int32_t *) addr, value) +#elif SIZEOF_VOID_P == 8 && OPAL_HAVE_ATOMIC_SWAP_64 +#define opal_atomic_swap_ptr(addr, value) opal_atomic_swap_64((int64_t *) addr, value) +#endif + +#endif /* (OPAL_HAVE_ATOMIC_SWAP_32 || OPAL_HAVE_ATOMIC_SWAP_64) */ + #if defined(DOXYGEN) || (OPAL_HAVE_ATOMIC_MATH_32 || OPAL_HAVE_ATOMIC_MATH_64) static inline void opal_atomic_add_xx(volatile void* addr,