#ifndef PMIX_SYS_ATOMIC_H
#define PMIX_SYS_ATOMIC_H 1
#include "src/include/pmix_config.h"
#include "src/include/pmix_stdatomic.h"
#if PMIX_USE_C11_ATOMICS
#include <stdatomic.h>
static inline void pmix_atomic_wmb(void)
{
atomic_thread_fence(memory_order_release);
}
static inline void pmix_atomic_rmb(void)
{
# if defined(PMIX_ATOMIC_X86_64)
__asm__ __volatile__("" : : : "memory");
# else
atomic_thread_fence(memory_order_acquire);
# endif
}
#define PMIX_ATOMIC_DEFINE_OP(type, bits, operator, name) \
static inline type \
pmix_atomic_fetch_##name##_##bits(pmix_atomic_##type *addr, type value) \
{ \
return atomic_fetch_##name##_explicit( \
addr, value, memory_order_relaxed); \
} \
\
static inline type \
pmix_atomic_##name##_fetch_##bits(pmix_atomic_##type *addr, type value) \
{ \
return atomic_fetch_##name##_explicit( \
addr, value, memory_order_relaxed) operator value; \
}
#elif PMIX_USE_GCC_BUILTIN_ATOMICS
static inline void pmix_atomic_wmb(void)
{
__atomic_thread_fence(__ATOMIC_RELEASE);
}
static inline void pmix_atomic_rmb(void)
{
#if defined(PMIX_ATOMIC_X86_64)
__asm__ __volatile__("" : : : "memory");
#else
__atomic_thread_fence(__ATOMIC_ACQUIRE);
#endif
}
#define PMIX_ATOMIC_DEFINE_OP(type, bits, operator, name) \
static inline type \
pmix_atomic_fetch_##name##_##bits(pmix_atomic_##type *addr, type value) \
{ \
return __atomic_fetch_##name(addr, value, __ATOMIC_RELAXED); \
} \
\
static inline type \
pmix_atomic_##name##_fetch_##bits(pmix_atomic_##type *addr, type value) \
{ \
return __atomic_##name##_fetch(addr, value, __ATOMIC_RELAXED); \
}
#else
#error OpenPMIx requires either C11 atomics support or GCC built-in atomics.
#endif
PMIX_ATOMIC_DEFINE_OP(int32_t, 32, +, add)
PMIX_ATOMIC_DEFINE_OP(int32_t, 32, &, and)
PMIX_ATOMIC_DEFINE_OP(int32_t, 32, |, or)
PMIX_ATOMIC_DEFINE_OP(int32_t, 32, ^, xor)
PMIX_ATOMIC_DEFINE_OP(int32_t, 32, -, sub)
#endif