Files
cpp-thirdparty/macx64/mpi/openmpi/include/pmix/src/include/pmix_atomic.h
Bassem Girgis d29ef955f5 Upgrade macos
2025-03-19 08:52:56 -05:00

143 lines
5.8 KiB
C

/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
* University Research and Technology
* Corporation. All rights reserved.
* Copyright (c) 2004-2006 The University of Tennessee and The University
* of Tennessee Research Foundation. All rights
* reserved.
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
* University of Stuttgart. All rights reserved.
* Copyright (c) 2004-2005 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
* Copyright (c) 2011 Sandia National Laboratories. All rights reserved.
* Copyright (c) 2011-2017 Los Alamos National Security, LLC. All rights
* reserved.
* Copyright (c) 2017 Research Organization for Information Science
* and Technology (RIST). All rights reserved.
* Copyright (c) 2018-2020 Intel, Inc. All rights reserved.
* Copyright (c) 2021-2022 Nanook Consulting All rights reserved.
* Copyright (c) Amazon.com, Inc. or its affiliates. All Rights
* reserved.
* Copyright (c) 2023 Triad National Security, LLC. All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
/** @file
*
* Atomic operations.
*
* This API is patterned after the FreeBSD kernel atomic interface
* (which is influenced by Intel's ia64 architecture). The
* FreeBSD interface is documented at
*
* http://www.freebsd.org/cgi/man.cgi?query=atomic&sektion=9
*
* Only the necessary subset of functions are implemented here.
*
* The following #defines will be true / false based on
* assembly support:
*
* - \c PMIX_HAVE_ATOMIC_MEM_BARRIER atomic memory barriers
* - \c PMIX_HAVE_ATOMIC_SPINLOCKS atomic spinlocks
* - \c PMIX_HAVE_ATOMIC_MATH_32 if 32 bit add/sub/compare-exchange can be done "atomically"
* - \c PMIX_HAVE_ATOMIC_MATH_64 if 64 bit add/sub/compare-exchange can be done "atomically"
*
* Note that for the Atomic math, atomic add/sub may be implemented as
* C code using pmix_atomic_compare_exchange. The appearance of atomic
* operation will be upheld in these cases.
*/
#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)
/* work around a bug in older gcc versions (observed in gcc 6.x)
* where acquire seems to get treated as a no-op instead of being
* equivalent to __asm__ __volatile__("": : :"memory") on 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; \
}
/* end of PMIX_USE_C11_ATOMICS */
#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)
/* work around a bug in older gcc versions where ACQUIRE seems to get
* treated as a no-op instead of being equivalent to
* __asm__ __volatile__("": : :"memory") */
__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); \
}
/* end of PMIX_USE_GCC_BUILTIN_ATOMICS */
#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 /* PMIX_SYS_ATOMIC_H */