- HandlerMinelayerData: BUILD_RTI Guards für RTI-Abhängigkeiten - svcTabCommon: Export-Header-Fix via Fallback-Target - TrainingAreaBase: Stub-Header für BUILD_RTI=OFF - ddsfts: Include-Pfad und Dependency-Fixes - BUILD_RTI=OFF Compilation vollständig unterstützt Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Entire-Checkpoint: 01M0JNZA586SACX1PRZ2DJAE5S
1623 lines
68 KiB
C
1623 lines
68 KiB
C
/*
|
|
* (c) Copyright, Real-Time Innovations, 2024.
|
|
* All rights reserved.
|
|
*
|
|
* No duplications, whole or partial, manual or electronic, may be made
|
|
* without express written permission. Any such copies, or
|
|
* revisions thereof, must display this notice unaltered.
|
|
* This code contains trade secrets of Real-Time Innovations, Inc.
|
|
*/
|
|
|
|
#ifndef osapi_atomic_h
|
|
#define osapi_atomic_h
|
|
|
|
/**
|
|
* @brief This header implements macros to perform atomic operations for all RTI
|
|
* supported platforms by using C11 Atomics, GCC built-in atomic support,
|
|
* Windows atomic intrinsics.
|
|
* @see https://en.cppreference.com/w/c/atomic for reference on C11 Atomics.
|
|
* @see
|
|
* https://gcc.gnu.org/onlinedocs/gcc-4.8.2/gcc/_005f_005fatomic-Builtins.html#g_t_005f_005fatomic-Builtins
|
|
* for reference on GCC built-in atomic support.
|
|
* @see
|
|
* https://learn.microsoft.com/en-us/cpp/intrinsics/intrinsics-available-on-all-architectures?view=msvc-140
|
|
* for reference on Windows atomic intrinsics.
|
|
*/
|
|
|
|
/*
|
|
* Check if the compiler supports C11 Atomics.
|
|
*/
|
|
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L \
|
|
&& !defined(__STDC_NO_ATOMICS__)
|
|
#define RTI_C11_ATOMIC_PRIMITIVES_ARE_SUPPORTED
|
|
#endif
|
|
|
|
/*
|
|
* Check if GCC's built-in atomic support is available (GCC >= 4.7).
|
|
*/
|
|
#if defined(__GNUC__) \
|
|
&& (__GNUC__ >= 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7))
|
|
#define RTI_GCC_ATOMIC_PRIMITIVES_ARE_SUPPORTED
|
|
#endif
|
|
|
|
/*
|
|
* Check if Windows' atomic intrinsics are available (VS2012 or higher)
|
|
*/
|
|
#if defined(_MSC_VER) && _MSC_VER >= 1700
|
|
#define RTI_MSVC_ATOMIC_PRIMITIVES_ARE_SUPPORTED
|
|
#endif
|
|
|
|
/*
|
|
* PURIFY_ATOMIC_OPERATIONS introduces the atomic variables in an anonymous
|
|
* struct to avoid using regular operations over atomic variables. The option is
|
|
* only enabled with PURIFY_TEST so it is not used in production, and it is
|
|
* disabled when ThreadSanitizer is enabled to allow annotations over atomic
|
|
* variables.
|
|
*/
|
|
#if defined(PURIFY_TEST) && !defined(RTI_THREAD_SANITIZER_IS_ENABLED)
|
|
#define PURIFY_ATOMIC_OPERATIONS
|
|
#endif
|
|
|
|
#if defined(RTI_C11_ATOMIC_PRIMITIVES_ARE_SUPPORTED)
|
|
#include <stdatomic.h>
|
|
#endif
|
|
|
|
#if defined(RTI_MSVC_ATOMIC_PRIMITIVES_ARE_SUPPORTED)
|
|
#include <intrin.h>
|
|
#endif
|
|
|
|
#include "osapi/osapi_dll.h"
|
|
#include "osapi/osapi_type.h"
|
|
#include "osapi/osapi_heap.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/**
|
|
* @brief The memory order for memory barriers and atomic operations.
|
|
* @details There are five options of memory barrier to choose:
|
|
* - Relaxed: no ordering constraints.
|
|
* - Acquire: a load operation with this memory order performs the acquire
|
|
* operation on the affected memory location: no reads or writes in the
|
|
* current thread can be reordered before this load. All writes in other
|
|
* threads that release the same atomic variable are visible in the current
|
|
* thread.
|
|
* - Release: a store operation with this memory order performs the release
|
|
* operation: no reads or writes in the current thread can be reordered after
|
|
* this store. All writes in the current thread are visible in other threads
|
|
* that acquire the same atomic variable (see Release-Acquire ordering below)
|
|
* and writes that carry a dependency into the atomic variable become visible
|
|
* in other threads that consume the same atomic.
|
|
* - Acquire-release: A read-modify-write operation with this memory order is
|
|
* both an acquire operation and a release operation. No memory reads or
|
|
* writes in the current thread can be reordered before the load, nor after
|
|
* the store. All writes in other threads that release the same atomic
|
|
* variable are visible before the modification and the modification is
|
|
* visible in other threads that acquire the same atomic variable.
|
|
* - Sequentially consistent: acquire-release memory barrier + all memory
|
|
* modifications before the barrier are ensured to be visible in all threads.
|
|
*
|
|
* Using these options in atomic operations allows three kind of approaches for
|
|
* memory ordering synchronization between threads:
|
|
* - Relaxed: no ordering constraints, only atomicity is guaranteed.
|
|
* - Acquire-release: all memory accesses (included non-atomic and relaxed
|
|
* atomic) before an atomic store tagged release are guaranteed to happen
|
|
* before an atomic load (in the same memory address) tagged acquire. This
|
|
* affects only to the involved threads, and no ordering is guaranteed between
|
|
* other threads.
|
|
* - Sequentially consistent: all memory accesses (included non-atomic and all
|
|
* atomic) are guaranteed to happen in a single total order, and this order
|
|
* is the same for all threads.
|
|
*
|
|
* Note we are ignoring consume memory order since most of the compilers have
|
|
* reported that they cannot implement it safely so, since it is mostly the
|
|
* acquire, we avoid using it.
|
|
* @see https://en.cppreference.com/w/c/atomic/memory_order for reference.
|
|
*/
|
|
typedef RTI_INT32 RTIOsapiAtomic_memoryOrder;
|
|
|
|
#if defined(RTI_C11_ATOMIC_PRIMITIVES_ARE_SUPPORTED)
|
|
#define RTI_OSAPI_ATOMIC_MEMORY_ORDER_RELAXED memory_order_relaxed
|
|
#define RTI_OSAPI_ATOMIC_MEMORY_ORDER_ACQUIRE memory_order_acquire
|
|
#define RTI_OSAPI_ATOMIC_MEMORY_ORDER_RELEASE memory_order_release
|
|
#define RTI_OSAPI_ATOMIC_MEMORY_ORDER_ACQUIRE_RELEASE memory_order_acq_rel
|
|
#define RTI_OSAPI_ATOMIC_MEMORY_ORDER_SEQ_CONSISTENT memory_order_seq_cst
|
|
#elif defined(RTI_GCC_ATOMIC_PRIMITIVES_ARE_SUPPORTED)
|
|
#define RTI_OSAPI_ATOMIC_MEMORY_ORDER_RELAXED __ATOMIC_RELAXED
|
|
#define RTI_OSAPI_ATOMIC_MEMORY_ORDER_ACQUIRE __ATOMIC_ACQUIRE
|
|
#define RTI_OSAPI_ATOMIC_MEMORY_ORDER_RELEASE __ATOMIC_RELEASE
|
|
#define RTI_OSAPI_ATOMIC_MEMORY_ORDER_ACQUIRE_RELEASE __ATOMIC_ACQ_REL
|
|
#define RTI_OSAPI_ATOMIC_MEMORY_ORDER_SEQ_CONSISTENT __ATOMIC_SEQ_CST
|
|
#else
|
|
#define RTI_OSAPI_ATOMIC_MEMORY_ORDER_RELAXED 0
|
|
#define RTI_OSAPI_ATOMIC_MEMORY_ORDER_ACQUIRE 1
|
|
#define RTI_OSAPI_ATOMIC_MEMORY_ORDER_RELEASE 2
|
|
#define RTI_OSAPI_ATOMIC_MEMORY_ORDER_ACQUIRE_RELEASE 3
|
|
#define RTI_OSAPI_ATOMIC_MEMORY_ORDER_SEQ_CONSISTENT 4
|
|
#endif
|
|
|
|
/**
|
|
* @brief Establishes memory synchronization ordering of non-atomic and relaxed
|
|
* atomic accesses, ensuring at least the memory order constraints specified by
|
|
* the memoryOrder__ argument.
|
|
* @param memoryOrder__ \b In. The memory order constraints to be established.
|
|
*/
|
|
RTIOsapiDllExport void RTIOsapiAtomic_memoryBarrier(
|
|
RTIOsapiAtomic_memoryOrder memoryOrder);
|
|
|
|
/**
|
|
* @brief Declare a variable of type type__ as atomic.
|
|
* @details This variable cannot be initialized directly but using
|
|
* RTIOsapiAtomic_initialize.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
/*
|
|
* Define atomic types as an struct in malloc plan (non-production build) so
|
|
* we do not mix atomic and non-atomic operations.
|
|
*/
|
|
#if defined(RTI_C11_ATOMIC_PRIMITIVES_ARE_SUPPORTED)
|
|
#define RTI_ATOMIC(type__) \
|
|
struct { \
|
|
_Atomic(type__) value; \
|
|
}
|
|
#elif defined(RTI_GCC_ATOMIC_PRIMITIVES_ARE_SUPPORTED) \
|
|
|| defined(RTI_MSVC_ATOMIC_PRIMITIVES_ARE_SUPPORTED)
|
|
#define RTI_ATOMIC(type__) \
|
|
struct { \
|
|
type__ value; \
|
|
}
|
|
#else
|
|
#error "No atomic primitives are supported"
|
|
#endif
|
|
#else
|
|
#if defined(RTI_C11_ATOMIC_PRIMITIVES_ARE_SUPPORTED)
|
|
#define RTI_ATOMIC(type__) _Atomic(type__)
|
|
#elif defined(RTI_GCC_ATOMIC_PRIMITIVES_ARE_SUPPORTED) \
|
|
|| defined(RTI_MSVC_ATOMIC_PRIMITIVES_ARE_SUPPORTED)
|
|
#define RTI_ATOMIC(type__) type__
|
|
#else
|
|
#error "No atomic primitives are supported"
|
|
#endif
|
|
#endif
|
|
|
|
/**
|
|
* @brief Initializes an atomic variable, perform a non-atomic store.
|
|
* @param var__ \b In. A pointer to the variable to be initialized.
|
|
* @param value__ \b In. The value to initialize the variable with.
|
|
* @details Note that this operation is not thread-safe, it is not an atomic
|
|
* operation. This operation is needed because an atomic object can contain more
|
|
* fields than the underlying type to make atomicity and synchronization work,
|
|
* and this API ensures the correct initialization of these other fields. This
|
|
* is mandatory only for variables with automatic storage duration, since static
|
|
* or thread-local storage duration variables are guaranteed to be initialized
|
|
* in a valid state with the default (zero) initialization.
|
|
* Note this is also a way to perform a non-atomic store operation.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTIOsapiAtomic_initialize(var__, value__) \
|
|
RTIOsapiAtomic_initializeI(&(var__)->value, value__)
|
|
#else
|
|
#define RTIOsapiAtomic_initialize(var__, value__) \
|
|
RTIOsapiAtomic_initializeI(var__, value__)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Placeholder initializer to allow structs with atomic types to be
|
|
* initialized with compound literal initializers. As this is only a
|
|
* placeholder, RTIOsapiAtomic_initialize SHALL be called to initialize all
|
|
* atomic variables in the struct.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTI_OSAPI_ATOMIC_LITERAL_PLACEHOLDER(value__) \
|
|
{ \
|
|
value__ \
|
|
}
|
|
#else
|
|
#define RTI_OSAPI_ATOMIC_LITERAL_PLACEHOLDER(value__) (value__)
|
|
#endif
|
|
|
|
/**************************** Atomic add operation ****************************/
|
|
|
|
/**
|
|
* @brief Atomically adds value__ to the 8 bits (RTI_UINT8 or RTI_INT8) variable
|
|
* pointed by var__.
|
|
* @param var__ \b In/Out. The pointer to the variable to be modified. Cannot be
|
|
* NULL.
|
|
* @param value__ \b In. The value to be added.
|
|
* @param memoryOrder__ \b In. The memory order constraints to be established.
|
|
* All memory orderings are allowed.
|
|
* @return The value held previously by the atomic object.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTIOsapiAtomic_add8(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_add8I(&(var__)->value, value__, memoryOrder__)
|
|
#else
|
|
#define RTIOsapiAtomic_add8(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_add8I(var__, value__, memoryOrder__)
|
|
#endif
|
|
|
|
/**
|
|
* @brief The unsigned version of RTIOsapiAtomic_add8. It should be used
|
|
* whenever the return value is used in an operation.
|
|
* @details Signed chars needs to be casted to unsigned before convert to a
|
|
* larger type. See SEI CERT STR34-C rule for more details. This is a problem in
|
|
* Windows where, even if atomic APIs can be used for both unsigned and signed
|
|
* types, they accept only signed types (the sign is ignore). When the return
|
|
* value of an atomic operation over an unsigned char is compare against another
|
|
* unsigned char, it is considered as a signed char - unsigned char comparison,
|
|
* and a integer promotion is performed. It breaks the STR34-C rule, since the
|
|
* signed char is promoted to a larger size directly.
|
|
*
|
|
* @see RTIOsapiAtomic_add8
|
|
*/
|
|
#if defined(RTI_MSVC_ATOMIC_PRIMITIVES_ARE_SUPPORTED)
|
|
#define RTIOsapiAtomic_add8u(var__, value__, memoryOrder__) \
|
|
((RTI_UINT8) RTIOsapiAtomic_add8(var__, value__, memoryOrder__))
|
|
#else
|
|
#define RTIOsapiAtomic_add8u(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_add8(var__, value__, memoryOrder__)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Atomically adds value__ to the 16 bits (RTI_UINT16 or RTI_INT16)
|
|
* variable pointed by var__.
|
|
* @param var__ \b In/Out. The pointer to the variable to be modified. Cannot be
|
|
* NULL.
|
|
* @param value__ \b In. The value to be added.
|
|
* @param memoryOrder__ \b In. The memory order constraints to be established.
|
|
* All memory orderings are allowed.
|
|
* @return The value held previously by the atomic object.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTIOsapiAtomic_add16(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_add16I(&(var__)->value, value__, memoryOrder__)
|
|
#else
|
|
#define RTIOsapiAtomic_add16(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_add16I(var__, value__, memoryOrder__)
|
|
#endif
|
|
|
|
/**
|
|
* @brief The unsigned version of RTIOsapiAtomic_add16. It should be used
|
|
* whenever the return value is used in an operation.
|
|
* @details On Windows, even if atomic APIs can be used for both unsigned and
|
|
* signed types, they accept only signed types (the sign is ignored). When the
|
|
* return value of an atomic operation over an unsigned short is compared
|
|
* against another unsigned short, it is treated as a signed short - unsigned
|
|
* short comparison, and integer promotion is performed. The signed short is
|
|
* promoted to a larger signed integer, causing sign-extension for values with
|
|
* bit 15 set (i.e., any value >= 32768). This breaks SEI CERT INT02-C and can
|
|
* cause the comparison to yield incorrect results.
|
|
*
|
|
* @see RTIOsapiAtomic_add16
|
|
*/
|
|
#if defined(RTI_MSVC_ATOMIC_PRIMITIVES_ARE_SUPPORTED)
|
|
#define RTIOsapiAtomic_add16u(var__, value__, memoryOrder__) \
|
|
((RTI_UINT16) RTIOsapiAtomic_add16(var__, value__, memoryOrder__))
|
|
#else
|
|
#define RTIOsapiAtomic_add16u(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_add16(var__, value__, memoryOrder__)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Atomically adds value__ to the 32 bits (RTI_UINT32 or RTI_INT32)
|
|
* variable pointed by var__.
|
|
* @param var__ \b In/Out. The pointer to the variable to be modified. Cannot be
|
|
* NULL.
|
|
* @param value__ \b In. The value to be added.
|
|
* @param memoryOrder__ \b In. The memory order constraints to be established.
|
|
* All memory orderings are allowed.
|
|
* @return The value held previously by the atomic object.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTIOsapiAtomic_add32(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_add32I(&(var__)->value, value__, memoryOrder__)
|
|
#else
|
|
#define RTIOsapiAtomic_add32(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_add32I(var__, value__, memoryOrder__)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Atomically adds value__ to the 64 bits (RTI_UINT64 or RTI_INT64)
|
|
* variable pointed by var__.
|
|
* @param var__ \b In/Out. The pointer to the variable to be modified. Cannot be
|
|
* NULL.
|
|
* @param value__ \b In. The value to be added.
|
|
* @param memoryOrder__ \b In. The memory order constraints to be established.
|
|
* All memory orderings are allowed.
|
|
* @return The value held previously by the atomic object.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTIOsapiAtomic_add64(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_add64I(&(var__)->value, value__, memoryOrder__)
|
|
#else
|
|
#define RTIOsapiAtomic_add64(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_add64I(var__, value__, memoryOrder__)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Atomically adds value__ to the pointer pointed by var__.
|
|
* @param var__ \b In/Out. The pointer to the pointer to be modified. Cannot be
|
|
* NULL.
|
|
* @param type__ \b In. The type of the pointer to be modified.
|
|
* @param value__ \b In. The value to be added.
|
|
* @param memoryOrder__ \b In. The memory order constraints to be established.
|
|
* All memory orderings are allowed.
|
|
* @return The value held previously by the atomic object.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTIOsapiAtomic_addPtr(var__, type__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_addPtrI(&(var__)->value, type__, value__, memoryOrder__)
|
|
#else
|
|
#define RTIOsapiAtomic_addPtr(var__, type__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_addPtrI(var__, type__, value__, memoryOrder__)
|
|
#endif
|
|
|
|
/**************************** Atomic sub operation ****************************/
|
|
|
|
/**
|
|
* @brief Atomically subtract value__ to the 8 bits (RTI_UINT8 or RTI_INT8)
|
|
* variable pointed by var__.
|
|
* @param var__ \b In/Out. A pointer to the variable to be modified. Cannot be
|
|
* NULL.
|
|
* @param value__ \b In. The value to be subtract.
|
|
* @param memoryOrder__ \b In. The memory order constraints to be established.
|
|
* All memory orderings are allowed.
|
|
* @return The value held previously by the atomic object.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTIOsapiAtomic_sub8(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_sub8I(&(var__)->value, value__, memoryOrder__)
|
|
#else
|
|
#define RTIOsapiAtomic_sub8(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_sub8I(var__, value__, memoryOrder__)
|
|
#endif
|
|
|
|
/**
|
|
* @brief The unsigned version of RTIOsapiAtomic_sub8. It should be used
|
|
* whenever the return value is used in an operation.
|
|
* @details Signed chars needs to be casted to unsigned before convert to a
|
|
* larger type. See SEI CERT STR34-C rule for more details. This is a problem in
|
|
* Windows where, even if atomic APIs can be used for both unsigned and signed
|
|
* types, they accept only signed types (the sign is ignore). When the return
|
|
* value of an atomic operation over an unsigned char is compare against another
|
|
* unsigned char, it is considered as a signed char - unsigned char comparison,
|
|
* and a integer promotion is performed. It breaks the STR34-C rule, since the
|
|
* signed char is promoted to a larger size directly.
|
|
*
|
|
* @see RTIOsapiAtomic_sub8
|
|
*/
|
|
#if defined(RTI_MSVC_ATOMIC_PRIMITIVES_ARE_SUPPORTED)
|
|
#define RTIOsapiAtomic_sub8u(var__, value__, memoryOrder__) \
|
|
((RTI_UINT8) RTIOsapiAtomic_sub8(var__, value__, memoryOrder__))
|
|
#else
|
|
#define RTIOsapiAtomic_sub8u(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_sub8(var__, value__, memoryOrder__)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Atomically subtract value__ to the 16 bits (RTI_UINT16 or RTI_INT16)
|
|
* variable pointed by var__.
|
|
* @param var__ \b In/Out. A pointer to the variable to be modified. Cannot be
|
|
* NULL.
|
|
* @param value__ \b In. The value to be subtract.
|
|
* @param memoryOrder__ \b In. The memory order constraints to be established.
|
|
* All memory orderings are allowed.
|
|
* @return The value held previously by the atomic object.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTIOsapiAtomic_sub16(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_sub16I(&(var__)->value, value__, memoryOrder__)
|
|
#else
|
|
#define RTIOsapiAtomic_sub16(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_sub16I(var__, value__, memoryOrder__)
|
|
#endif
|
|
|
|
/**
|
|
* @brief The unsigned version of RTIOsapiAtomic_sub16. It should be used
|
|
* whenever the return value is used in an operation.
|
|
* @details On Windows, even if atomic APIs can be used for both unsigned and
|
|
* signed types, they accept only signed types (the sign is ignored). When the
|
|
* return value of an atomic operation over an unsigned short is compared
|
|
* against another unsigned short, it is treated as a signed short - unsigned
|
|
* short comparison, and integer promotion is performed. The signed short is
|
|
* promoted to a larger signed integer, causing sign-extension for values with
|
|
* bit 15 set (i.e., any value >= 32768). This breaks SEI CERT INT02-C and can
|
|
* cause the comparison to yield incorrect results.
|
|
*
|
|
* @see RTIOsapiAtomic_sub16
|
|
*/
|
|
#if defined(RTI_MSVC_ATOMIC_PRIMITIVES_ARE_SUPPORTED)
|
|
#define RTIOsapiAtomic_sub16u(var__, value__, memoryOrder__) \
|
|
((RTI_UINT16) RTIOsapiAtomic_sub16(var__, value__, memoryOrder__))
|
|
#else
|
|
#define RTIOsapiAtomic_sub16u(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_sub16(var__, value__, memoryOrder__)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Atomically subtract value__ to the 32 bits (RTI_UINT32 or RTI_INT32)
|
|
* variable pointed by var__.
|
|
* @param var__ \b In/Out. A pointer to the variable to be modified. Cannot be
|
|
* NULL.
|
|
* @param value__ \b In. The value to be subtract.
|
|
* @param memoryOrder__ \b In. The memory order constraints to be established.
|
|
* All memory orderings are allowed.
|
|
* @return The value held previously by the atomic object.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTIOsapiAtomic_sub32(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_sub32I(&(var__)->value, value__, memoryOrder__)
|
|
#else
|
|
#define RTIOsapiAtomic_sub32(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_sub32I(var__, value__, memoryOrder__)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Atomically subtract value__ to the 64 bits (RTI_UINT64 or RTI_INT64)
|
|
* variable pointed by var__.
|
|
* @param var__ \b In/Out. A pointer to the variable to be modified. Cannot be
|
|
* NULL.
|
|
* @param value__ \b In. The value to be subtract.
|
|
* @param memoryOrder__ \b In. The memory order constraints to be established.
|
|
* All memory orderings are allowed.
|
|
* @return The value held previously by the atomic object.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTIOsapiAtomic_sub64(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_sub64I(&(var__)->value, value__, memoryOrder__)
|
|
#else
|
|
#define RTIOsapiAtomic_sub64(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_sub64I(var__, value__, memoryOrder__)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Atomically subtract value__ to pointer pointed by var__.
|
|
* @param var__ \b In/Out. A pointer to the pointer to be modified. Cannot be
|
|
* NULL.
|
|
* @param type__ \b In. The type of the pointer to be modified.
|
|
* @param value__ \b In. The value to be subtract.
|
|
* @param memoryOrder__ \b In. The memory order constraints to be established.
|
|
* All memory orderings are allowed.
|
|
* @return The value held previously by the atomic object.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTIOsapiAtomic_subPtr(var__, type__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_subPtrI(&(var__)->value, type__, value__, memoryOrder__)
|
|
#else
|
|
#define RTIOsapiAtomic_subPtr(var__, type__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_subPtrI(var__, type__, value__, memoryOrder__)
|
|
#endif
|
|
|
|
/*************************** Atomic store operation ***************************/
|
|
|
|
/**
|
|
* @brief Atomically store value__ to the 8 bits (RTI_UINT8 or RTI_INT8)
|
|
* variable pointed by var__.
|
|
* @param var__ \b In/Out. A pointer to the variable to be modified.
|
|
* Cannot be NULL.
|
|
* @param value__ \b In. The value to be stored.
|
|
* @param memoryOrder__ \b In. The memory order constraints to be established.
|
|
* Only RTI_OSAPI_ATOMIC_MEMORY_ORDER_RELAXED,
|
|
* RTI_OSAPI_ATOMIC_MEMORY_ORDER_RELEASE, and
|
|
* RTI_OSAPI_ATOMIC_MEMORY_ORDER_SEQ_CONSISTENT are allowed.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTIOsapiAtomic_store8(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_store8I(&(var__)->value, value__, memoryOrder__)
|
|
#else
|
|
#define RTIOsapiAtomic_store8(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_store8I(var__, value__, memoryOrder__)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Atomically store value__ to the 16 bits (RTI_UINT16 or RTI_INT16)
|
|
* variable pointed by var__.
|
|
* @param var__ \b In/Out. A pointer to the variable to be modified.
|
|
* Cannot be NULL.
|
|
* @param value__ \b In. The value to be stored.
|
|
* @param memoryOrder__ \b In. The memory order constraints to be established.
|
|
* Only RTI_OSAPI_ATOMIC_MEMORY_ORDER_RELAXED,
|
|
* RTI_OSAPI_ATOMIC_MEMORY_ORDER_RELEASE, and
|
|
* RTI_OSAPI_ATOMIC_MEMORY_ORDER_SEQ_CONSISTENT are allowed.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTIOsapiAtomic_store16(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_store16I(&(var__)->value, value__, memoryOrder__)
|
|
#else
|
|
#define RTIOsapiAtomic_store16(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_store16I(var__, value__, memoryOrder__)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Atomically store value__ to the 32 bits (RTI_UINT32 or RTI_INT32)
|
|
* variable pointed by var__.
|
|
* @param var__ \b In/Out. A pointer to the variable to be modified.
|
|
* Cannot be NULL.
|
|
* @param value__ \b In. The value to be stored.
|
|
* @param memoryOrder__ \b In. The memory order constraints to be established.
|
|
* Only RTI_OSAPI_ATOMIC_MEMORY_ORDER_RELAXED,
|
|
* RTI_OSAPI_ATOMIC_MEMORY_ORDER_RELEASE, and
|
|
* RTI_OSAPI_ATOMIC_MEMORY_ORDER_SEQ_CONSISTENT are allowed.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTIOsapiAtomic_store32(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_store32I(&(var__)->value, value__, memoryOrder__)
|
|
#else
|
|
#define RTIOsapiAtomic_store32(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_store32I(var__, value__, memoryOrder__)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Atomically store value__ to the 64 bits (RTI_UINT64 or RTI_INT64)
|
|
* variable pointed by var__.
|
|
* @param var__ \b In/Out. A pointer to the variable to be modified.
|
|
* Cannot be NULL.
|
|
* @param value__ \b In. The value to be stored.
|
|
* @param memoryOrder__ \b In. The memory order constraints to be established.
|
|
* Only RTI_OSAPI_ATOMIC_MEMORY_ORDER_RELAXED,
|
|
* RTI_OSAPI_ATOMIC_MEMORY_ORDER_RELEASE, and
|
|
* RTI_OSAPI_ATOMIC_MEMORY_ORDER_SEQ_CONSISTENT are allowed.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTIOsapiAtomic_store64(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_store64I(&(var__)->value, value__, memoryOrder__)
|
|
#else
|
|
#define RTIOsapiAtomic_store64(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_store64I(var__, value__, memoryOrder__)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Atomically store the pointer value__ to the pointer-to-pointer var__.
|
|
* @param var__ \b In/Out. A pointer to the pointer to be modified. Cannot be
|
|
* NULL.
|
|
* @param value__ \b In. The value to be stored.
|
|
* @param memoryOrder__ \b In. The memory order constraints to be established.
|
|
* Only RTI_OSAPI_ATOMIC_MEMORY_ORDER_RELAXED,
|
|
* RTI_OSAPI_ATOMIC_MEMORY_ORDER_RELEASE, and
|
|
* RTI_OSAPI_ATOMIC_MEMORY_ORDER_SEQ_CONSISTENT are allowed.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTIOsapiAtomic_storePtr(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_storePtrI(&(var__)->value, value__, memoryOrder__)
|
|
#else
|
|
#define RTIOsapiAtomic_storePtr(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_storePtrI(var__, value__, memoryOrder__)
|
|
#endif
|
|
|
|
/*************************** Atomic load operation ****************************/
|
|
|
|
/**
|
|
* @brief Atomically load the value of the 8 bits (RTI_UINT8 or RTI_INT8)
|
|
* variable pointed by var__. Cannot be NULL.
|
|
* @param var__ \b In. A pointer to the variable to load from.
|
|
* @param memoryOrder__ \b In. The memory order constraints to be established.
|
|
* Only RTI_OSAPI_ATOMIC_MEMORY_ORDER_RELAXED,
|
|
* RTI_OSAPI_ATOMIC_MEMORY_ORDER_ACQUIRE, and
|
|
* RTI_OSAPI_ATOMIC_MEMORY_ORDER_SEQ_CONSISTENT are allowed.
|
|
* @return The value loaded from var__.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTIOsapiAtomic_load8(var__, memoryOrder__) \
|
|
RTIOsapiAtomic_load8I(&(var__)->value, memoryOrder__)
|
|
#else
|
|
#define RTIOsapiAtomic_load8(var__, memoryOrder__) \
|
|
RTIOsapiAtomic_load8I(var__, memoryOrder__)
|
|
#endif
|
|
|
|
/**
|
|
* @brief The unsigned version of RTIOsapiAtomic_load8. It should be used
|
|
* whenever the return value is used in an operation.
|
|
* @details Signed chars needs to be casted to unsigned before convert to a
|
|
* larger type. See SEI CERT STR34-C rule for more details. This is a problem in
|
|
* Windows where, even if atomic APIs can be used for both unsigned and signed
|
|
* types, they accept only signed types (the sign is ignore). When the return
|
|
* value of an atomic operation over an unsigned char is compare against another
|
|
* unsigned char, it is considered as a signed char - unsigned char comparison,
|
|
* and a integer promotion is performed. It breaks the STR34-C rule, since the
|
|
* signed char is promoted to a larger size directly.
|
|
*
|
|
* @see RTIOsapiAtomic_load8
|
|
*/
|
|
#if defined(RTI_MSVC_ATOMIC_PRIMITIVES_ARE_SUPPORTED)
|
|
#define RTIOsapiAtomic_load8u(var__, memoryOrder__) \
|
|
((RTI_UINT8) RTIOsapiAtomic_load8(var__, memoryOrder__))
|
|
#else
|
|
#define RTIOsapiAtomic_load8u(var__, memoryOrder__) \
|
|
RTIOsapiAtomic_load8(var__, memoryOrder__)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Atomically load the value of the 16 bits (RTI_UINT16 or RTI_INT16)
|
|
* variable pointed by var__. Cannot be NULL.
|
|
* @param var__ \b In. A pointer to the variable to load from.
|
|
* @param memoryOrder__ \b In. The memory order constraints to be established.
|
|
* Only RTI_OSAPI_ATOMIC_MEMORY_ORDER_RELAXED,
|
|
* RTI_OSAPI_ATOMIC_MEMORY_ORDER_ACQUIRE, and
|
|
* RTI_OSAPI_ATOMIC_MEMORY_ORDER_SEQ_CONSISTENT are allowed.
|
|
* @return The value loaded from var__.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTIOsapiAtomic_load16(var__, memoryOrder__) \
|
|
RTIOsapiAtomic_load16I(&(var__)->value, memoryOrder__)
|
|
#else
|
|
#define RTIOsapiAtomic_load16(var__, memoryOrder__) \
|
|
RTIOsapiAtomic_load16I(var__, memoryOrder__)
|
|
#endif
|
|
|
|
/**
|
|
* @brief The unsigned version of RTIOsapiAtomic_load16. It should be used
|
|
* whenever the return value is used in an operation.
|
|
* @details On Windows, even if atomic APIs can be used for both unsigned and
|
|
* signed types, they accept only signed types (the sign is ignored). When the
|
|
* return value of an atomic operation over an unsigned short is compared
|
|
* against another unsigned short, it is treated as a signed short - unsigned
|
|
* short comparison, and integer promotion is performed. The signed short is
|
|
* promoted to a larger signed integer, causing sign-extension for values with
|
|
* bit 15 set (i.e., any value >= 32768). This breaks SEI CERT INT02-C and can
|
|
* cause the comparison to yield incorrect results.
|
|
*
|
|
* @see RTIOsapiAtomic_load16
|
|
*/
|
|
#if defined(RTI_MSVC_ATOMIC_PRIMITIVES_ARE_SUPPORTED)
|
|
#define RTIOsapiAtomic_load16u(var__, memoryOrder__) \
|
|
((RTI_UINT16) RTIOsapiAtomic_load16(var__, memoryOrder__))
|
|
#else
|
|
#define RTIOsapiAtomic_load16u(var__, memoryOrder__) \
|
|
RTIOsapiAtomic_load16(var__, memoryOrder__)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Atomically load the value of the 32 bits (RTI_UINT32 or RTI_INT32)
|
|
* variable pointed by var__. Cannot be NULL.
|
|
* @param var__ \b In. A pointer to the variable to load from.
|
|
* @param memoryOrder__ \b In. The memory order constraints to be established.
|
|
* Only RTI_OSAPI_ATOMIC_MEMORY_ORDER_RELAXED,
|
|
* RTI_OSAPI_ATOMIC_MEMORY_ORDER_ACQUIRE, and
|
|
* RTI_OSAPI_ATOMIC_MEMORY_ORDER_SEQ_CONSISTENT are allowed.
|
|
* @return The value loaded from var__.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTIOsapiAtomic_load32(var__, memoryOrder__) \
|
|
RTIOsapiAtomic_load32I(&(var__)->value, memoryOrder__)
|
|
#else
|
|
#define RTIOsapiAtomic_load32(var__, memoryOrder__) \
|
|
RTIOsapiAtomic_load32I(var__, memoryOrder__)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Atomically load the value of the 64 bits (RTI_UINT64 or RTI_INT64)
|
|
* variable pointed by var__. Cannot be NULL.
|
|
* @param var__ \b In. A pointer to the variable to load from.
|
|
* @param memoryOrder__ \b In. The memory order constraints to be established.
|
|
* Only RTI_OSAPI_ATOMIC_MEMORY_ORDER_RELAXED,
|
|
* RTI_OSAPI_ATOMIC_MEMORY_ORDER_ACQUIRE, and
|
|
* RTI_OSAPI_ATOMIC_MEMORY_ORDER_SEQ_CONSISTENT are allowed.
|
|
* @return The value loaded from var__.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTIOsapiAtomic_load64(var__, memoryOrder__) \
|
|
RTIOsapiAtomic_load64I(&(var__)->value, memoryOrder__)
|
|
#else
|
|
#define RTIOsapiAtomic_load64(var__, memoryOrder__) \
|
|
RTIOsapiAtomic_load64I(var__, memoryOrder__)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Atomically load the pointer pointed by var__. Cannot be NULL.
|
|
* @param type__ \b In. The type of the pointer to be modified.
|
|
* @param var__ \b In. A pointer to the pointer to load.
|
|
* @param memoryOrder__ \b In. The memory order constraints to be established.
|
|
* Only RTI_OSAPI_ATOMIC_MEMORY_ORDER_RELAXED,
|
|
* RTI_OSAPI_ATOMIC_MEMORY_ORDER_ACQUIRE, and
|
|
* RTI_OSAPI_ATOMIC_MEMORY_ORDER_SEQ_CONSISTENT are allowed.
|
|
* @return The pointer loaded from var__.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTIOsapiAtomic_loadPtr(var__, type__, memoryOrder__) \
|
|
RTIOsapiAtomic_loadPtrI(&(var__)->value, type__, memoryOrder__)
|
|
#else
|
|
#define RTIOsapiAtomic_loadPtr(var__, type__, memoryOrder__) \
|
|
RTIOsapiAtomic_loadPtrI(var__, type__, memoryOrder__)
|
|
#endif
|
|
|
|
/*************************** Atomic exchange operation ************************/
|
|
|
|
/**
|
|
* @brief Atomically exchange the value of the 8 bits (RTI_UINT8 or RTI_INT8)
|
|
* variable pointed by var__ with value__ and returns the value previously hold
|
|
* by var__.
|
|
* @param var__ \b In/Out. A pointer to the variable to be modified. Cannot be
|
|
* NULL.
|
|
* @param value__ \b In. The value to be exchanged.
|
|
* @param memoryOrder__ \b In. The memory order constraints to be established.
|
|
* All memory orderings are allowed.
|
|
* @return The value held previously by the atomic object.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTIOsapiAtomic_exchange8(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_exchange8I(&(var__)->value, value__, memoryOrder__)
|
|
#else
|
|
#define RTIOsapiAtomic_exchange8(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_exchange8I(var__, value__, memoryOrder__)
|
|
#endif
|
|
|
|
/**
|
|
* @brief The unsigned version of RTIOsapiAtomic_exchange8. It should be used
|
|
* whenever the return value is used in an operation.
|
|
* @details Signed chars needs to be casted to unsigned before convert to a
|
|
* larger type. See SEI CERT STR34-C rule for more details. This is a problem in
|
|
* Windows where, even if atomic APIs can be used for both unsigned and signed
|
|
* types, they accept only signed types (the sign is ignore). When the return
|
|
* value of an atomic operation over an unsigned char is compare against another
|
|
* unsigned char, it is considered as a signed char - unsigned char comparison,
|
|
* and a integer promotion is performed. It breaks the STR34-C rule, since the
|
|
* signed char is promoted to a larger size directly.
|
|
*
|
|
* @see RTIOsapiAtomic_exchange8
|
|
*/
|
|
#if defined(RTI_MSVC_ATOMIC_PRIMITIVES_ARE_SUPPORTED)
|
|
#define RTIOsapiAtomic_exchange8u(var__, value__, memoryOrder__) \
|
|
((RTI_UINT8) RTIOsapiAtomic_exchange8(var__, value__, memoryOrder__))
|
|
#else
|
|
#define RTIOsapiAtomic_exchange8u(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_exchange8(var__, value__, memoryOrder__)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Atomically exchange the value of the 16 bits (RTI_UINT16 or RTI_INT16)
|
|
* variable pointed by var__ with value__ and returns the value previously hold
|
|
* by var__.
|
|
* @param var__ \b In/Out. A pointer to the variable to be modified. Cannot be
|
|
* NULL.
|
|
* @param value__ \b In. The value to be exchanged.
|
|
* @param memoryOrder__ \b In. The memory order constraints to be established.
|
|
* All memory orderings are allowed.
|
|
* @return The value held previously by the atomic object.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTIOsapiAtomic_exchange16(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_exchange16I(&(var__)->value, value__, memoryOrder__)
|
|
#else
|
|
#define RTIOsapiAtomic_exchange16(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_exchange16I(var__, value__, memoryOrder__)
|
|
#endif
|
|
|
|
/**
|
|
* @brief The unsigned version of RTIOsapiAtomic_exchange16. It should be used
|
|
* whenever the return value is used in an operation.
|
|
* @details On Windows, even if atomic APIs can be used for both unsigned and
|
|
* signed types, they accept only signed types (the sign is ignored). When the
|
|
* return value of an atomic operation over an unsigned short is compared
|
|
* against another unsigned short, it is treated as a signed short - unsigned
|
|
* short comparison, and integer promotion is performed. The signed short is
|
|
* promoted to a larger signed integer, causing sign-extension for values with
|
|
* bit 15 set (i.e., any value >= 32768). This breaks SEI CERT INT02-C and can
|
|
* cause the comparison to yield incorrect results. For example, any UDP port >=
|
|
* 32768 (including all ephemeral ports 49152-65535) will trigger a spurious
|
|
* false inequality when its exchanged value is compared against the original.
|
|
*
|
|
* @see RTIOsapiAtomic_exchange16
|
|
*/
|
|
#if defined(RTI_MSVC_ATOMIC_PRIMITIVES_ARE_SUPPORTED)
|
|
#define RTIOsapiAtomic_exchange16u(var__, value__, memoryOrder__) \
|
|
((RTI_UINT16) RTIOsapiAtomic_exchange16(var__, value__, memoryOrder__))
|
|
#else
|
|
#define RTIOsapiAtomic_exchange16u(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_exchange16(var__, value__, memoryOrder__)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Atomically exchange the value of the 32 bits (RTI_UINT32 or RTI_INT32)
|
|
* variable pointed by var__ with value__ and returns the value previously hold
|
|
* by var__.
|
|
* @param var__ \b In/Out. A pointer to the variable to be modified. Cannot be
|
|
* NULL.
|
|
* @param value__ \b In. The value to be exchanged.
|
|
* @param memoryOrder__ \b In. The memory order constraints to be established.
|
|
* All memory orderings are allowed.
|
|
* @return The value held previously by the atomic object.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTIOsapiAtomic_exchange32(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_exchange32I(&(var__)->value, value__, memoryOrder__)
|
|
#else
|
|
#define RTIOsapiAtomic_exchange32(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_exchange32I(var__, value__, memoryOrder__)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Atomically exchange the value of the 64 bits (RTI_UINT64 or RTI_INT64)
|
|
* variable pointed by var__ with value__ and returns the value previously hold
|
|
* by var__.
|
|
* @param var__ \b In/Out. A pointer to the variable to be modified. Cannot be
|
|
* NULL.
|
|
* @param value__ \b In. The value to be exchanged.
|
|
* @param memoryOrder__ \b In. The memory order constraints to be established.
|
|
* All memory orderings are allowed.
|
|
* @return The value held previously by the atomic object.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTIOsapiAtomic_exchange64(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_exchange64I(&(var__)->value, value__, memoryOrder__)
|
|
#else
|
|
#define RTIOsapiAtomic_exchange64(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_exchange64I(var__, value__, memoryOrder__)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Atomically exchange the pointer pointed by var__ with value__ and
|
|
* returns the value previously hold by var__.
|
|
* @param var__ \b In/Out. A pointer to the pointer to be modified. Cannot be
|
|
* NULL.
|
|
* @param type__ \b In. The type of the pointer to be modified.
|
|
* @param value__ \b In. The value to be exchanged.
|
|
* @param memoryOrder__ \b In. The memory order constraints to be established.
|
|
* All memory orderings are allowed.
|
|
* @return The value held previously by the atomic object.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTIOsapiAtomic_exchangePtr(var__, type__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_exchangePtrI( \
|
|
&(var__)->value, \
|
|
type__, \
|
|
value__, \
|
|
memoryOrder__)
|
|
#else
|
|
#define RTIOsapiAtomic_exchangePtr(var__, type__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_exchangePtrI(var__, type__, value__, memoryOrder__)
|
|
#endif
|
|
|
|
/*************************** Atomic compare-exchange operation ****************/
|
|
|
|
/**
|
|
* @brief Atomically compare the value of the 8 bits (RTI_UINT8 or RTI_INT8)
|
|
* variable pointed by var__ with expected__ and if equal, store desired__ in
|
|
* var__. If not equal, store var__ in expected__. Weak means that the operation
|
|
* may fail spuriously, but the operation will not block if the value of var__
|
|
* is not in cache. Because of that, this API shall be always used within a loop
|
|
* (see SEI CERT CON41-C).
|
|
* @param var__ \b In/Out. A pointer to the variable to be modified. Cannot be
|
|
* NULL.
|
|
* @param expected__ \b In. A pointer to the variable to compare with.
|
|
* @param desired__ \b In. The value to store if the comparison is successful.
|
|
* @param memoryOrderSuccess__ \b In. The memory order constraints to be
|
|
* established when operation success (read-modify-write operation over var__).
|
|
* All memory orderings are allowed.
|
|
* @param memoryOrderFail__ \b In. The memory order constraints to be
|
|
* established when operation fails (only read var__). Only
|
|
* RTI_OSAPI_ATOMIC_MEMORY_ORDER_RELAXED, RTI_OSAPI_ATOMIC_MEMORY_ORDER_ACQUIRE,
|
|
* and RTI_OSAPI_ATOMIC_MEMORY_ORDER_SEQ_CONSISTENT are allowed. Cannot specify
|
|
* an stronger memory order than memoryOrderSuccess__.
|
|
* @return RTI_TRUE if the operation succeed and desired__ has been copied to
|
|
* var__, RTI_FALSE when the operation failed and var__ has been copied to
|
|
* expected__.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTIOsapiAtomic_compareExchangeWeak8( \
|
|
var__, \
|
|
expected__, \
|
|
desired__, \
|
|
memoryOrderSuccess__, \
|
|
memoryOrderFail__) \
|
|
RTIOsapiAtomic_compareExchangeWeak8I( \
|
|
&(var__)->value, \
|
|
expected__, \
|
|
desired__, \
|
|
memoryOrderSuccess__, \
|
|
memoryOrderFail__)
|
|
#else
|
|
#define RTIOsapiAtomic_compareExchangeWeak8( \
|
|
var__, \
|
|
expected__, \
|
|
desired__, \
|
|
memoryOrderSuccess__, \
|
|
memoryOrderFail__) \
|
|
RTIOsapiAtomic_compareExchangeWeak8I( \
|
|
var__, \
|
|
expected__, \
|
|
desired__, \
|
|
memoryOrderSuccess__, \
|
|
memoryOrderFail__)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Atomically compare the value of the 16 bits (RTI_UINT16 or RTI_INT16)
|
|
* variable pointed by var__ with expected__ and if equal, store desired__ in
|
|
* var__. If not equal, store var__ in expected__. Weak means that the operation
|
|
* may fail spuriously, but the operation will not block if the value of var__
|
|
* is not in cache. Because of that, this API shall be always used within a loop
|
|
* (see SEI CERT CON41-C).
|
|
* @param var__ \b In/Out. A pointer to the variable to be modified. Cannot be
|
|
* NULL.
|
|
* @param expected__ \b In. A pointer to the variable to compare with.
|
|
* @param desired__ \b In. The value to store if the comparison is successful.
|
|
* @param memoryOrderSuccess__ \b In. The memory order constraints to be
|
|
* established when operation success (read-modify-write operation over var__).
|
|
* All memory orderings are allowed.
|
|
* @param memoryOrderFail__ \b In. The memory order constraints to be
|
|
* established when operation fails (only read var__). Only
|
|
* RTI_OSAPI_ATOMIC_MEMORY_ORDER_RELAXED, RTI_OSAPI_ATOMIC_MEMORY_ORDER_ACQUIRE,
|
|
* and RTI_OSAPI_ATOMIC_MEMORY_ORDER_SEQ_CONSISTENT are allowed. Cannot specify
|
|
* an stronger memory order than memoryOrderSuccess__.
|
|
* @return RTI_TRUE if the operation succeed and desired__ has been copied to
|
|
* var__, RTI_FALSE when the operation failed and var__ has been copied to
|
|
* expected__.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTIOsapiAtomic_compareExchangeWeak16( \
|
|
var__, \
|
|
expected__, \
|
|
desired__, \
|
|
memoryOrderSuccess__, \
|
|
memoryOrderFail__) \
|
|
RTIOsapiAtomic_compareExchangeWeak16I( \
|
|
&(var__)->value, \
|
|
expected__, \
|
|
desired__, \
|
|
memoryOrderSuccess__, \
|
|
memoryOrderFail__)
|
|
#else
|
|
#define RTIOsapiAtomic_compareExchangeWeak16( \
|
|
var__, \
|
|
expected__, \
|
|
desired__, \
|
|
memoryOrderSuccess__, \
|
|
memoryOrderFail__) \
|
|
RTIOsapiAtomic_compareExchangeWeak16I( \
|
|
var__, \
|
|
expected__, \
|
|
desired__, \
|
|
memoryOrderSuccess__, \
|
|
memoryOrderFail__)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Atomically compare the value of the 32 bits (RTI_UINT32 or RTI_INT32)
|
|
* variable pointed by var__ with expected__ and if equal, store desired__ in
|
|
* var__. If not equal, store var__ in expected__. Weak means that the operation
|
|
* may fail spuriously, but the operation will not block if the value of var__
|
|
* is not in cache. Because of that, this API shall be always used within a loop
|
|
* (see SEI CERT CON41-C).
|
|
* @param var__ \b In/Out. A pointer to the variable to be modified. Cannot be
|
|
* NULL.
|
|
* @param expected__ \b In. A pointer to the variable to compare with.
|
|
* @param desired__ \b In. The value to store if the comparison is successful.
|
|
* @param memoryOrderSuccess__ \b In. The memory order constraints to be
|
|
* established when operation success (read-modify-write operation over var__).
|
|
* All memory orderings are allowed.
|
|
* @param memoryOrderFail__ \b In. The memory order constraints to be
|
|
* established when operation fails (only read var__). Only
|
|
* RTI_OSAPI_ATOMIC_MEMORY_ORDER_RELAXED, RTI_OSAPI_ATOMIC_MEMORY_ORDER_ACQUIRE,
|
|
* and RTI_OSAPI_ATOMIC_MEMORY_ORDER_SEQ_CONSISTENT are allowed. Cannot specify
|
|
* an stronger memory order than memoryOrderSuccess__.
|
|
* @return RTI_TRUE if the operation succeed and desired__ has been copied to
|
|
* var__, RTI_FALSE when the operation failed and var__ has been copied to
|
|
* expected__.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTIOsapiAtomic_compareExchangeWeak32( \
|
|
var__, \
|
|
expected__, \
|
|
desired__, \
|
|
memoryOrderSuccess__, \
|
|
memoryOrderFail__) \
|
|
RTIOsapiAtomic_compareExchangeWeak32I( \
|
|
&(var__)->value, \
|
|
expected__, \
|
|
desired__, \
|
|
memoryOrderSuccess__, \
|
|
memoryOrderFail__)
|
|
#else
|
|
#define RTIOsapiAtomic_compareExchangeWeak32( \
|
|
var__, \
|
|
expected__, \
|
|
desired__, \
|
|
memoryOrderSuccess__, \
|
|
memoryOrderFail__) \
|
|
RTIOsapiAtomic_compareExchangeWeak32I( \
|
|
var__, \
|
|
expected__, \
|
|
desired__, \
|
|
memoryOrderSuccess__, \
|
|
memoryOrderFail__)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Atomically compare the value of the 64 bits (RTI_UINT64 or RTI_INT64)
|
|
* variable pointed by var__ with expected__ and if equal, store desired__ in
|
|
* var__. If not equal, store var__ in expected__.Weak means that the operation
|
|
* may fail spuriously, but the operation will not block if the value of var__
|
|
* is not in cache. Because of that, this API shall be always used within a loop
|
|
* (see SEI CERT CON41-C).
|
|
* @param var__ \b In/Out. A pointer to the variable to be modified. Cannot be
|
|
* NULL.
|
|
* @param expected__ \b In. The variable to compare with.
|
|
* @param desired__ \b In. A pointer to the value to store if the comparison is
|
|
* successful.
|
|
* @param memoryOrderSuccess__ \b In. The memory order constraints to be
|
|
* established when operation success (read-modify-write operation over var__).
|
|
* All memory orderings are allowed.
|
|
* @param memoryOrderFail__ \b In. The memory order constraints to be
|
|
* established when operation fails (only read var__). Only
|
|
* RTI_OSAPI_ATOMIC_MEMORY_ORDER_RELAXED, RTI_OSAPI_ATOMIC_MEMORY_ORDER_ACQUIRE,
|
|
* and RTI_OSAPI_ATOMIC_MEMORY_ORDER_SEQ_CONSISTENT are allowed. Cannot specify
|
|
* an stronger memory order than memoryOrderSuccess__.
|
|
* @return RTI_TRUE if the operation succeed and desired__ has been copied to
|
|
* var__, RTI_FALSE when the operation failed and var__ has been copied to
|
|
* expected__.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTIOsapiAtomic_compareExchangeWeak64( \
|
|
var__, \
|
|
expected__, \
|
|
desired__, \
|
|
memoryOrderSuccess__, \
|
|
memoryOrderFail__) \
|
|
RTIOsapiAtomic_compareExchangeWeak64I( \
|
|
&(var__)->value, \
|
|
expected__, \
|
|
desired__, \
|
|
memoryOrderSuccess__, \
|
|
memoryOrderFail__)
|
|
#else
|
|
#define RTIOsapiAtomic_compareExchangeWeak64( \
|
|
var__, \
|
|
expected__, \
|
|
desired__, \
|
|
memoryOrderSuccess__, \
|
|
memoryOrderFail__) \
|
|
RTIOsapiAtomic_compareExchangeWeak64I( \
|
|
var__, \
|
|
expected__, \
|
|
desired__, \
|
|
memoryOrderSuccess__, \
|
|
memoryOrderFail__)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Atomically compare the pointer pointed by var__ with expected__ and if
|
|
* equal, store desired__ in var__. If not equal, store var__ in expected__.
|
|
* Weak means that the operation may fail spuriously, but the operation will not
|
|
* block if the value of var__ is not in cache. Because of that, this API shall
|
|
* be always used within a loop (see SEI CERT CON41-C).
|
|
* @param var__ \b In/Out. A pointer to the variable to be modified. Cannot be
|
|
* NULL.
|
|
* @param expected__ \b In. A pointer to the variable to compare with.
|
|
* @param desired__ \b In. The value to store if the comparison is successful.
|
|
* @param memoryOrderSuccess__ \b In. The memory order constraints to be
|
|
* established when operation success (read-modify-write operation over var__).
|
|
* All memory orderings are allowed.
|
|
* @param memoryOrderFail__ \b In. The memory order constraints to be
|
|
* established when operation fails (only read var__). Only
|
|
* RTI_OSAPI_ATOMIC_MEMORY_ORDER_RELAXED, RTI_OSAPI_ATOMIC_MEMORY_ORDER_ACQUIRE,
|
|
* and RTI_OSAPI_ATOMIC_MEMORY_ORDER_SEQ_CONSISTENT are allowed. Cannot specify
|
|
* an stronger memory order than memoryOrderSuccess__.
|
|
* @return RTI_TRUE if the operation succeed and desired__ has been copied to
|
|
* var__, RTI_FALSE when the operation failed and var__ has been copied to
|
|
* expected__.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTIOsapiAtomic_compareExchangeWeakPtr( \
|
|
var__, \
|
|
expected__, \
|
|
desired__, \
|
|
memoryOrderSuccess__, \
|
|
memoryOrderFail__) \
|
|
RTIOsapiAtomic_compareExchangeWeakPtrI( \
|
|
&(var__)->value, \
|
|
expected__, \
|
|
desired__, \
|
|
memoryOrderSuccess__, \
|
|
memoryOrderFail__)
|
|
#else
|
|
#define RTIOsapiAtomic_compareExchangeWeakPtr( \
|
|
var__, \
|
|
expected__, \
|
|
desired__, \
|
|
memoryOrderSuccess__, \
|
|
memoryOrderFail__) \
|
|
RTIOsapiAtomic_compareExchangeWeakPtrI( \
|
|
var__, \
|
|
expected__, \
|
|
desired__, \
|
|
memoryOrderSuccess__, \
|
|
memoryOrderFail__)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Atomically compare the value of the 8 bits (RTI_UINT8 or RTI_INT8)
|
|
* variable pointed by var__ with expected__ and if equal, store desired__ in
|
|
* var__. If not equal, store var__ in expected__. Strong means that the
|
|
* operation will not fail spuriously, but the operation will block until the
|
|
* value of var__ is in cache. If you are using this API within a loop, consider
|
|
* the weak version.
|
|
* @param var__ \b In/Out. A pointer to the variable to be modified. Cannot be
|
|
* NULL.
|
|
* @param expected__ \b In. A pointer to the variable to compare with.
|
|
* @param desired__ \b In. The value to store if the comparison is successful.
|
|
* @param memoryOrderSuccess__ \b In. The memory order constraints to be
|
|
* established when operation success (read-modify-write operation over var__).
|
|
* All memory orderings are allowed.
|
|
* @param memoryOrderFail__ \b In. The memory order constraints to be
|
|
* established when operation fails (only read var__). Only
|
|
* RTI_OSAPI_ATOMIC_MEMORY_ORDER_RELAXED, RTI_OSAPI_ATOMIC_MEMORY_ORDER_ACQUIRE,
|
|
* and RTI_OSAPI_ATOMIC_MEMORY_ORDER_SEQ_CONSISTENT are allowed. Cannot specify
|
|
* an stronger memory order than memoryOrderSuccess__.
|
|
* @return RTI_TRUE if the operation succeed and desired__ has been copied to
|
|
* var__, RTI_FALSE when the operation failed and var__ has been copied to
|
|
* expected__.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTIOsapiAtomic_compareExchangeStrong8( \
|
|
var__, \
|
|
expected__, \
|
|
desired__, \
|
|
memoryOrderSuccess__, \
|
|
memoryOrderFail__) \
|
|
RTIOsapiAtomic_compareExchangeStrong8I( \
|
|
&(var__)->value, \
|
|
expected__, \
|
|
desired__, \
|
|
memoryOrderSuccess__, \
|
|
memoryOrderFail__)
|
|
#else
|
|
#define RTIOsapiAtomic_compareExchangeStrong8( \
|
|
var__, \
|
|
expected__, \
|
|
desired__, \
|
|
memoryOrderSuccess__, \
|
|
memoryOrderFail__) \
|
|
RTIOsapiAtomic_compareExchangeStrong8I( \
|
|
var__, \
|
|
expected__, \
|
|
desired__, \
|
|
memoryOrderSuccess__, \
|
|
memoryOrderFail__)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Atomically compare the value of the 16 bits (RTI_UINT16 or RTI_INT16)
|
|
* variable pointed by var__ with expected__ and if equal, store desired__ in
|
|
* var__. If not equal, store var__ in expected__. Strong means that the
|
|
* operation will not fail spuriously, but the operation will block until the
|
|
* value of var__ is in cache. If you are using this API within a loop, consider
|
|
* the weak version.
|
|
* @param var__ \b In/Out. A pointer to the variable to be modified. Cannot be
|
|
* NULL.
|
|
* @param expected__ \b In. A pointer to the variable to compare with.
|
|
* @param desired__ \b In. The value to store if the comparison is successful.
|
|
* @param memoryOrderSuccess__ \b In. The memory order constraints to be
|
|
* established when operation success (read-modify-write operation over var__).
|
|
* All memory orderings are allowed.
|
|
* @param memoryOrderFail__ \b In. The memory order constraints to be
|
|
* established when operation fails (only read var__). Only
|
|
* RTI_OSAPI_ATOMIC_MEMORY_ORDER_RELAXED, RTI_OSAPI_ATOMIC_MEMORY_ORDER_ACQUIRE,
|
|
* and RTI_OSAPI_ATOMIC_MEMORY_ORDER_SEQ_CONSISTENT are allowed. Cannot specify
|
|
* an stronger memory order than memoryOrderSuccess__.
|
|
* @return RTI_TRUE if the operation succeed and desired__ has been copied to
|
|
* var__, RTI_FALSE when the operation failed and var__ has been copied to
|
|
* expected__.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTIOsapiAtomic_compareExchangeStrong16( \
|
|
var__, \
|
|
expected__, \
|
|
desired__, \
|
|
memoryOrderSuccess__, \
|
|
memoryOrderFail__) \
|
|
RTIOsapiAtomic_compareExchangeStrong16I( \
|
|
&(var__)->value, \
|
|
expected__, \
|
|
desired__, \
|
|
memoryOrderSuccess__, \
|
|
memoryOrderFail__)
|
|
#else
|
|
#define RTIOsapiAtomic_compareExchangeStrong16( \
|
|
var__, \
|
|
expected__, \
|
|
desired__, \
|
|
memoryOrderSuccess__, \
|
|
memoryOrderFail__) \
|
|
RTIOsapiAtomic_compareExchangeStrong16I( \
|
|
var__, \
|
|
expected__, \
|
|
desired__, \
|
|
memoryOrderSuccess__, \
|
|
memoryOrderFail__)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Atomically compare the value of the 32 bits (RTI_UINT32 or RTI_INT32)
|
|
* variable pointed by var__ with expected__ and if equal, store desired__ in
|
|
* var__. If not equal, store var__ in expected__. Strong means that the
|
|
* operation will not fail spuriously, but the operation will block until the
|
|
* value of var__ is in cache. If you are using this API within a loop, consider
|
|
* the weak version.
|
|
* @param var__ \b In/Out. A pointer to the variable to be modified. Cannot be
|
|
* NULL.
|
|
* @param expected__ \b In. A pointer to the variable to compare with.
|
|
* @param desired__ \b In. The value to store if the comparison is successful.
|
|
* @param memoryOrderSuccess__ \b In. The memory order constraints to be
|
|
* established when operation success (read-modify-write operation over var__).
|
|
* All memory orderings are allowed.
|
|
* @param memoryOrderFail__ \b In. The memory order constraints to be
|
|
* established when operation fails (only read var__). Only
|
|
* RTI_OSAPI_ATOMIC_MEMORY_ORDER_RELAXED, RTI_OSAPI_ATOMIC_MEMORY_ORDER_ACQUIRE,
|
|
* and RTI_OSAPI_ATOMIC_MEMORY_ORDER_SEQ_CONSISTENT are allowed. Cannot specify
|
|
* an stronger memory order than memoryOrderSuccess__.
|
|
* @return RTI_TRUE if the operation succeed and desired__ has been copied to
|
|
* var__, RTI_FALSE when the operation failed and var__ has been copied to
|
|
* expected__.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTIOsapiAtomic_compareExchangeStrong32( \
|
|
var__, \
|
|
expected__, \
|
|
desired__, \
|
|
memoryOrderSuccess__, \
|
|
memoryOrderFail__) \
|
|
RTIOsapiAtomic_compareExchangeStrong32I( \
|
|
&(var__)->value, \
|
|
expected__, \
|
|
desired__, \
|
|
memoryOrderSuccess__, \
|
|
memoryOrderFail__)
|
|
#else
|
|
#define RTIOsapiAtomic_compareExchangeStrong32( \
|
|
var__, \
|
|
expected__, \
|
|
desired__, \
|
|
memoryOrderSuccess__, \
|
|
memoryOrderFail__) \
|
|
RTIOsapiAtomic_compareExchangeStrong32I( \
|
|
var__, \
|
|
expected__, \
|
|
desired__, \
|
|
memoryOrderSuccess__, \
|
|
memoryOrderFail__)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Atomically compare the value of the 64 bits (RTI_UINT64 or RTI_INT64)
|
|
* variable pointed by var__ with expected__ and if equal, store desired__ in
|
|
* var__. If not equal, store var__ in expected__. Strong means that the
|
|
* operation will not fail spuriously, but the operation will block until the
|
|
* value of var__ is in cache. If you are using this API within a loop, consider
|
|
* the weak version.
|
|
* @param var__ \b In/Out. A pointer to the variable to be modified. Cannot be
|
|
* NULL.
|
|
* @param expected__ \b In. A pointer to the variable to compare with.
|
|
* @param desired__ \b In. The value to store if the comparison is successful.
|
|
* @param memoryOrderSuccess__ \b In. The memory order constraints to be
|
|
* established when operation success (read-modify-write operation over var__).
|
|
* All memory orderings are allowed.
|
|
* @param memoryOrderFail__ \b In. The memory order constraints to be
|
|
* established when operation fails (only read var__). Only
|
|
* RTI_OSAPI_ATOMIC_MEMORY_ORDER_RELAXED, RTI_OSAPI_ATOMIC_MEMORY_ORDER_ACQUIRE,
|
|
* and RTI_OSAPI_ATOMIC_MEMORY_ORDER_SEQ_CONSISTENT are allowed. Cannot specify
|
|
* an stronger memory order than memoryOrderSuccess__.
|
|
* @return RTI_TRUE if the operation succeed and desired__ has been copied to
|
|
* var__, RTI_FALSE when the operation failed and var__ has been copied to
|
|
* expected__.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTIOsapiAtomic_compareExchangeStrong64( \
|
|
var__, \
|
|
expected__, \
|
|
desired__, \
|
|
memoryOrderSuccess__, \
|
|
memoryOrderFail__) \
|
|
RTIOsapiAtomic_compareExchangeStrong64I( \
|
|
&(var__)->value, \
|
|
expected__, \
|
|
desired__, \
|
|
memoryOrderSuccess__, \
|
|
memoryOrderFail__)
|
|
#else
|
|
#define RTIOsapiAtomic_compareExchangeStrong64( \
|
|
var__, \
|
|
expected__, \
|
|
desired__, \
|
|
memoryOrderSuccess__, \
|
|
memoryOrderFail__) \
|
|
RTIOsapiAtomic_compareExchangeStrong64I( \
|
|
var__, \
|
|
expected__, \
|
|
desired__, \
|
|
memoryOrderSuccess__, \
|
|
memoryOrderFail__)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Atomically compare the pointer pointed by var__ with expected__ and if
|
|
* equal, store desired__ in var__. If not equal, store var__ in expected__.
|
|
* Strong means that the operation will not fail spuriously, but the operation
|
|
* will block until the value of var__ is in cache. If you are using this API
|
|
* within a loop, consider the weak version.
|
|
* @param var__ \b In/Out. A pointer to the variable to be modified. Cannot be
|
|
* NULL.
|
|
* @param expected__ \b In. A pointer to the variable to compare with.
|
|
* @param desired__ \b In. The value to store if the comparison is successful.
|
|
* @param memoryOrderSuccess__ \b In. The memory order constraints to be
|
|
* established when operation success (read-modify-write operation over var__).
|
|
* All memory orderings are allowed.
|
|
* @param memoryOrderFail__ \b In. The memory order constraints to be
|
|
* established when operation fails (only read var__). Only
|
|
* RTI_OSAPI_ATOMIC_MEMORY_ORDER_RELAXED, RTI_OSAPI_ATOMIC_MEMORY_ORDER_ACQUIRE,
|
|
* and RTI_OSAPI_ATOMIC_MEMORY_ORDER_SEQ_CONSISTENT are allowed. Cannot specify
|
|
* an stronger memory order than memoryOrderSuccess__.
|
|
* @return RTI_TRUE if the operation succeed and desired__ has been copied to
|
|
* var__, RTI_FALSE when the operation failed and var__ has been copied to
|
|
* expected__.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTIOsapiAtomic_compareExchangeStrongPtr( \
|
|
var__, \
|
|
expected__, \
|
|
desired__, \
|
|
memoryOrderSuccess__, \
|
|
memoryOrderFail__) \
|
|
RTIOsapiAtomic_compareExchangeStrongPtrI( \
|
|
&(var__)->value, \
|
|
expected__, \
|
|
desired__, \
|
|
memoryOrderSuccess__, \
|
|
memoryOrderFail__)
|
|
#else
|
|
#define RTIOsapiAtomic_compareExchangeStrongPtr( \
|
|
var__, \
|
|
expected__, \
|
|
desired__, \
|
|
memoryOrderSuccess__, \
|
|
memoryOrderFail__) \
|
|
RTIOsapiAtomic_compareExchangeStrongPtrI( \
|
|
var__, \
|
|
expected__, \
|
|
desired__, \
|
|
memoryOrderSuccess__, \
|
|
memoryOrderFail__)
|
|
#endif
|
|
|
|
/*********************** Atomic fetch-and-or operation ************************/
|
|
|
|
/**
|
|
* @brief Atomically replaces the value of the 8 bits (RTI_UINT8 or RTI_INT8)
|
|
* variable var__ with the result of bitwise OR between the old value of var__
|
|
* and value__.
|
|
* @param var__ \b In/Out. A pointer to the variable to be modified. Cannot be
|
|
* NULL.
|
|
* @param value__ \b In. The value to OR with the value pointed by var__.
|
|
* @param memoryOrder__ \b In. The memory order constraints to be established.
|
|
* All memory orderings are allowed.
|
|
* @return The value held previously by the atomic object.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTIOsapiAtomic_or8(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_or8I(&(var__)->value, value__, memoryOrder__)
|
|
#else
|
|
#define RTIOsapiAtomic_or8(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_or8I(var__, value__, memoryOrder__)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Atomically replaces the value of the 16 bits (RTI_UINT16 or RTI_INT16)
|
|
* variable var__ with the result of bitwise OR between the old value of var__
|
|
* and value__.
|
|
* @param var__ \b In/Out. A pointer to the variable to be modified. Cannot be
|
|
* NULL.
|
|
* @param value__ \b In. The value to OR with the value pointed by var__.
|
|
* @param memoryOrder__ \b In. The memory order constraints to be established.
|
|
* All memory orderings are allowed.
|
|
* @return The value held previously by the atomic object.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTIOsapiAtomic_or16(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_or16I(&(var__)->value, value__, memoryOrder__)
|
|
#else
|
|
#define RTIOsapiAtomic_or16(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_or16I(var__, value__, memoryOrder__)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Atomically replaces the value of the 32 bits (RTI_UINT32 or RTI_INT32)
|
|
* variable var__ with the result of bitwise OR between the old value of var__
|
|
* and value__.
|
|
* @param var__ \b In/Out. A pointer to the variable to be modified. Cannot be
|
|
* NULL.
|
|
* @param value__ \b In. The value to OR with the value pointed by var__.
|
|
* @param memoryOrder__ \b In. The memory order constraints to be established.
|
|
* All memory orderings are allowed.
|
|
* @return The value held previously by the atomic object.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTIOsapiAtomic_or32(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_or32I(&(var__)->value, value__, memoryOrder__)
|
|
#else
|
|
#define RTIOsapiAtomic_or32(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_or32I(var__, value__, memoryOrder__)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Atomically replaces the value of the 64 bits (RTI_UINT64 or RTI_INT64)
|
|
* variable var__ with the result of bitwise OR between the old value of var__
|
|
* and value__.
|
|
* @param var__ \b In/Out. A pointer to the variable to be modified. Cannot be
|
|
* NULL.
|
|
* @param value__ \b In. The value to OR with the value pointed by var__.
|
|
* @param memoryOrder__ \b In. The memory order constraints to be established.
|
|
* All memory orderings are allowed.
|
|
* @return The value held previously by the atomic object.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTIOsapiAtomic_or64(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_or64I(&(var__)->value, value__, memoryOrder__)
|
|
#else
|
|
#define RTIOsapiAtomic_or64(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_or64I(var__, value__, memoryOrder__)
|
|
#endif
|
|
|
|
/*********************** Atomic fetch-and-xor operation ***********************/
|
|
|
|
/**
|
|
* @brief Atomically replaces the value of the 8 bits (RTI_UINT8 or RTI_INT8)
|
|
* variable var__ with the result of bitwise XOR between the old value of var__
|
|
* and value__.
|
|
* @param var__ \b In/Out. A pointer to the variable to be modified. Cannot be
|
|
* NULL.
|
|
* @param value__ \b In. The value to XOR with the value pointed by var__.
|
|
* @param memoryOrder__ \b In. The memory order constraints to be established.
|
|
* All memory orderings are allowed.
|
|
* @return The value held previously by the atomic object.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTIOsapiAtomic_xor8(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_xor8I(&(var__)->value, value__, memoryOrder__)
|
|
#else
|
|
#define RTIOsapiAtomic_xor8(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_xor8I(var__, value__, memoryOrder__)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Atomically replaces the value of the 16 bits (RTI_UINT16 or RTI_INT16)
|
|
* variable var__ with the result of bitwise XOR between the old value of var__
|
|
* and value__.
|
|
* @param var__ \b In/Out. A pointer to the variable to be modified. Cannot be
|
|
* NULL.
|
|
* @param value__ \b In. The value to XOR with the value pointed by var__.
|
|
* @param memoryOrder__ \b In. The memory order constraints to be established.
|
|
* All memory orderings are allowed.
|
|
* @return The value held previously by the atomic object.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTIOsapiAtomic_xor16(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_xor16I(&(var__)->value, value__, memoryOrder__)
|
|
#else
|
|
#define RTIOsapiAtomic_xor16(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_xor16I(var__, value__, memoryOrder__)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Atomically replaces the value of the 32 bits (RTI_UINT32 or RTI_INT32)
|
|
* variable var__ with the result of bitwise XOR between the old value of var__
|
|
* and value__.
|
|
* @param var__ \b In/Out. A pointer to the variable to be modified. Cannot be
|
|
* NULL.
|
|
* @param value__ \b In. The value to XOR with the value pointed by var__.
|
|
* @param memoryOrder__ \b In. The memory order constraints to be established.
|
|
* All memory orderings are allowed.
|
|
* @return The value held previously by the atomic object.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTIOsapiAtomic_xor32(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_xor32I(&(var__)->value, value__, memoryOrder__)
|
|
#else
|
|
#define RTIOsapiAtomic_xor32(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_xor32I(var__, value__, memoryOrder__)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Atomically replaces the value of the 64 bits (RTI_UINT64 or RTI_INT64)
|
|
* variable var__ with the result of bitwise XOR between the old value of var__
|
|
* and value__.
|
|
* @param var__ \b In/Out. A pointer to the variable to be modified. Cannot be
|
|
* NULL.
|
|
* @param value__ \b In. The value to XOR with the value pointed by var__.
|
|
* @param memoryOrder__ \b In. The memory order constraints to be established.
|
|
* All memory orderings are allowed.
|
|
* @return The value held previously by the atomic object.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTIOsapiAtomic_xor64(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_xor64I(&(var__)->value, value__, memoryOrder__)
|
|
#else
|
|
#define RTIOsapiAtomic_xor64(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_xor64I(var__, value__, memoryOrder__)
|
|
#endif
|
|
|
|
/*********************** Atomic fetch-and-and operation ***********************/
|
|
|
|
/**
|
|
* @brief Atomically replaces the value of the 8 bits (RTI_UINT8 or RTI_INT8)
|
|
* variable var__ with the result of bitwise AND between the old value of var__
|
|
* and value__.
|
|
* @param var__ \b In/Out. A pointer to the variable to be modified. Cannot be
|
|
* NULL.
|
|
* @param value__ \b In. The value to AND with the value pointed by var__.
|
|
* @param memoryOrder__ \b In. The memory order constraints to be established.
|
|
* All memory orderings are allowed.
|
|
* @return The value held previously by the atomic object.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTIOsapiAtomic_and8(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_and8I(&(var__)->value, value__, memoryOrder__)
|
|
#else
|
|
#define RTIOsapiAtomic_and8(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_and8I(var__, value__, memoryOrder__)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Atomically replaces the value of the 16 bits (RTI_UINT16 or RTI_INT16)
|
|
* variable var__ with the result of bitwise AND between the old value of var__
|
|
* and value__.
|
|
* @param var__ \b In/Out. A pointer to the variable to be modified. Cannot be
|
|
* NULL.
|
|
* @param value__ \b In. The value to AND with the value pointed by var__.
|
|
* @param memoryOrder__ \b In. The memory order constraints to be established.
|
|
* All memory orderings are allowed.
|
|
* @return The value held previously by the atomic object.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTIOsapiAtomic_and16(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_and16I(&(var__)->value, value__, memoryOrder__)
|
|
#else
|
|
#define RTIOsapiAtomic_and16(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_and16I(var__, value__, memoryOrder__)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Atomically replaces the value of the 32 bits (RTI_UINT32 or RTI_INT32)
|
|
* variable var__ with the result of bitwise AND between the old value of var__
|
|
* and value__.
|
|
* @param var__ \b In/Out. A pointer to the variable to be modified. Cannot be
|
|
* NULL.
|
|
* @param value__ \b In. The value to AND with the value pointed by var__.
|
|
* @param memoryOrder__ \b In. The memory order constraints to be established.
|
|
* All memory orderings are allowed.
|
|
* @return The value held previously by the atomic object.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTIOsapiAtomic_and32(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_and32I(&(var__)->value, value__, memoryOrder__)
|
|
#else
|
|
#define RTIOsapiAtomic_and32(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_and32I(var__, value__, memoryOrder__)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Atomically replaces the value of the 64 bits (RTI_UINT64 or RTI_INT64)
|
|
* variable var__ with the result of bitwise AND between the old value of var__
|
|
* and value__.
|
|
* @param var__ \b In/Out. A pointer to the variable to be modified. Cannot be
|
|
* NULL.
|
|
* @param value__ \b In. The value to AND with the value pointed by var__.
|
|
* @param memoryOrder__ \b In. The memory order constraints to be established.
|
|
* All memory orderings are allowed.
|
|
* @return The value held previously by the atomic object.
|
|
*/
|
|
#if defined(PURIFY_ATOMIC_OPERATIONS)
|
|
#define RTIOsapiAtomic_and64(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_and64I(&(var__)->value, value__, memoryOrder__)
|
|
#else
|
|
#define RTIOsapiAtomic_and64(var__, value__, memoryOrder__) \
|
|
RTIOsapiAtomic_and64I(var__, value__, memoryOrder__)
|
|
#endif
|
|
|
|
#ifdef __cplusplus
|
|
} /* extern "C" */
|
|
#endif
|
|
|
|
#include "osapi/osapi_atomic_impl.h"
|
|
|
|
#endif /* osapi_atomic_h */
|