/*
 * Copyright (c) 2023, NVIDIA CORPORATION.  All rights reserved.
 *
 * NVIDIA CORPORATION and its licensors retain all intellectual property
 * and proprietary rights in and to this software, related documentation
 * and any modifications thereto.  Any use, reproduction, disclosure or
 * distribution of this software and related documentation without an express
 * license agreement from NVIDIA CORPORATION is strictly prohibited.
 */

#ifndef _NVHPC_STDATOMIC_H_
#define _NVHPC_STDATOMIC_H_

#include_next <stdatomic.h>

#if defined(atomic_fetch_add) && !defined(__cplusplus)

  /* When the atomic object being modified is a pointer rather than an integer,
     the argument to the C standard function atomic_fetch_add and related
     functions is the number of elements by which to adjust.  But the argument
     to the built-in function __atomic_fetch_add is the number of bytes.
     Change the macros that implement the C standard functions to forward to
     different built-in functions that expect the offset to be the number of
     elements. */

  #undef atomic_fetch_add
  #define atomic_fetch_add(ptr, val) \
    __atomic_fetch_add_pointer_aware((ptr), (val), __ATOMIC_SEQ_CST)

  #undef atomic_fetch_add_explicit
  #define atomic_fetch_add_explicit(ptr, val, mo) \
    __atomic_fetch_add_pointer_aware((ptr), (val), (mo))

  #undef atomic_fetch_sub
  #define atomic_fetch_sub(ptr, val) \
    __atomic_fetch_sub_pointer_aware((ptr), (val), __ATOMIC_SEQ_CST)

  #undef atomic_fetch_sub_explicit
  #define atomic_fetch_sub_explicit(ptr, val, mo) \
    __atomic_fetch_sub_pointer_aware((ptr), (val), (mo))

#endif

#endif
