diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2014-05-07 14:55:37 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2014-06-30 09:56:23 +0200 |
commit | 89f8eab5822163f9cd619828ec7191c33d868f9b (patch) | |
tree | b08332e87f40b39f31f8ebf3cede75c1041aec0d /cpukit | |
parent | smptests/smpmigration02: PR2183: Add test case (diff) | |
download | rtems-89f8eab5822163f9cd619828ec7191c33d868f9b.tar.bz2 |
score: Workaround for GCC 4.9 for atomic ops
The GCC 4.9 ships its own <stdatomic.h> which is not C++ compatible.
The suggested solution was to include <atomic> in case C++ is used.
This works at least with GCC 4.9. See also:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60932
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60940
Diffstat (limited to 'cpukit')
-rw-r--r-- | cpukit/score/include/rtems/score/atomic.h | 501 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/cpustdatomic.h | 629 |
2 files changed, 346 insertions, 784 deletions
diff --git a/cpukit/score/include/rtems/score/atomic.h b/cpukit/score/include/rtems/score/atomic.h index da5b48dc33..4ea735401b 100644 --- a/cpukit/score/include/rtems/score/atomic.h +++ b/cpukit/score/include/rtems/score/atomic.h @@ -1,10 +1,9 @@ /** - * @file rtems/score/atomic.h - * - * This include file defines the interface for all the atomic - * operations which can be used in the synchronization primitives - * or in the lock-less algorithms. You should not use these API - * in the other components directly. + * @file + * + * @ingroup ScoreAtomic + * + * @brief Atomic Operations API */ /* @@ -20,400 +19,134 @@ #include <rtems/score/cpuatomic.h> -#ifdef __cplusplus -extern "C" { -#endif - /** - * @defgroup RTEMS atomic interface + * @defgroup ScoreAtomic Atomic Operations + * + * @ingroup Score + * + * @brief Support for atomic operations. * + * Atomic operations can be used to implement low-level synchronization + * primitives on SMP systems, like spin locks. All atomic operations are + * defined in terms of C11 (ISO/IEC 9899:2011) or C++11 (ISO/IEC 14882:2011). + * For documentation use the standard documents. + * + * @{ */ -/**@{*/ +typedef CPU_atomic_Uint Atomic_Uint; -/** - * @brief atomic data initializer for static initialization. - */ -#define ATOMIC_INITIALIZER_UINT(value) CPU_ATOMIC_INITIALIZER_UINT(value) -#define ATOMIC_INITIALIZER_ULONG(value) CPU_ATOMIC_INITIALIZER_ULONG(value) -#define ATOMIC_INITIALIZER_PTR(value) CPU_ATOMIC_INITIALIZER_PTR(value) +typedef CPU_atomic_Ulong Atomic_Ulong; + +typedef CPU_atomic_Pointer Atomic_Pointer; + +typedef CPU_atomic_Flag Atomic_Flag; + +#define ATOMIC_ORDER_RELAXED CPU_ATOMIC_ORDER_RELAXED + +#define ATOMIC_ORDER_ACQUIRE CPU_ATOMIC_ORDER_ACQUIRE + +#define ATOMIC_ORDER_RELEASE CPU_ATOMIC_ORDER_RELEASE + +#define ATOMIC_ORDER_SEQ_CST CPU_ATOMIC_ORDER_SEQ_CST + +#define ATOMIC_INITIALIZER_UINT( value ) CPU_ATOMIC_INITIALIZER_UINT( value ) + +#define ATOMIC_INITIALIZER_ULONG( value ) CPU_ATOMIC_INITIALIZER_ULONG( value ) + +#define ATOMIC_INITIALIZER_PTR( value ) CPU_ATOMIC_INITIALIZER_PTR( value ) -/** - * @brief Initializes an atomic flag object to the cleared state. - */ #define ATOMIC_INITIALIZER_FLAG CPU_ATOMIC_INITIALIZER_FLAG -static inline void _Atomic_Fence( - Atomic_Order order -) -{ - _CPU_atomic_Fence( order ); -} +#define _Atomic_Fence( order ) _CPU_atomic_Fence( order ) -/** - * @brief Initializes an atomic type value into a atomic object. - * - * @param object an atomic type pointer of object. - * @param pointer a pointer to be stored into object. - */ -static inline void _Atomic_Init_uint( - volatile Atomic_Uint *object, - unsigned int value -) -{ - _CPU_atomic_Init_uint(object, value); -} - -static inline void _Atomic_Init_ulong( - volatile Atomic_Ulong *object, - unsigned long value -) -{ - _CPU_atomic_Init_ulong(object, value); -} - -static inline void _Atomic_Init_ptr( - volatile Atomic_Pointer *object, - void *pointer -) -{ - _CPU_atomic_Init_ptr(object, pointer); -} +#define _Atomic_Init_uint( obj, desired ) \ + _CPU_atomic_Init_uint( obj, desired ) -/** - * @brief Atomically load an atomic type value from atomic object. - * - * @param object an atomic type pointer of object. - * @param order a type of Atomic_Order. - * - * The order shall not be ATOMIC_ORDER_RELEASE. - */ -static inline unsigned int _Atomic_Load_uint( - volatile Atomic_Uint *object, - Atomic_Order order -) -{ - return _CPU_atomic_Load_uint( object, order ); -} - -static inline unsigned long _Atomic_Load_ulong( - volatile Atomic_Ulong *object, - Atomic_Order order -) -{ - return _CPU_atomic_Load_ulong( object, order ); -} - -static inline void *_Atomic_Load_ptr( - volatile Atomic_Pointer *object, - Atomic_Order order -) -{ - return _CPU_atomic_Load_ptr( object, order ); -} +#define _Atomic_Init_ulong( obj, desired ) \ + _CPU_atomic_Init_ulong( obj, desired ) -/** - * @brief Atomically store an atomic type value into a atomic object. - * - * @param object an atomic type pointer of object. - * @param value a value to be stored into object. - * @param order a type of Atomic_Order. - * - * The order shall not be ATOMIC_ORDER_ACQUIRE. - */ -static inline void _Atomic_Store_uint( - volatile Atomic_Uint *object, - unsigned int value, - Atomic_Order order -) -{ - _CPU_atomic_Store_uint( object, value, order ); -} - -static inline void _Atomic_Store_ulong( - volatile Atomic_Ulong *object, - unsigned long value, - Atomic_Order order -) -{ - _CPU_atomic_Store_ulong( object, value, order ); -} - -static inline void _Atomic_Store_ptr( - volatile Atomic_Pointer *object, - void *pointer, - Atomic_Order order -) -{ - _CPU_atomic_Store_ptr( object, pointer, order ); -} +#define _Atomic_Init_ptr( obj, desired ) \ + _CPU_atomic_Init_ptr( obj, desired ) -/** - * @brief Atomically load-add-store an atomic type value into object - * - * @param object a atomic type pointer of object. - * @param value a value to be add and store into object. - * @param order a type of Atomic_Order. - * - * @retval a result value before add ops. - */ -static inline unsigned int _Atomic_Fetch_add_uint( - volatile Atomic_Uint *object, - unsigned int value, - Atomic_Order order -) -{ - return _CPU_atomic_Fetch_add_uint( object, value, order ); -} - -static inline unsigned long _Atomic_Fetch_add_ulong( - volatile Atomic_Ulong *object, - unsigned long value, - Atomic_Order order -) -{ - return _CPU_atomic_Fetch_add_ulong( object, value, order ); -} - -static inline uintptr_t _Atomic_Fetch_add_ptr( - volatile Atomic_Pointer *object, - uintptr_t value, - Atomic_Order order -) -{ - return _CPU_atomic_Fetch_add_ptr( object, value, order ); -} +#define _Atomic_Load_uint( obj, order ) \ + _CPU_atomic_Load_uint( obj, order ) -/** - * @brief Atomically load-sub-store an atomic type value into object - * - * @param object a atomic type pointer of object. - * @param value a value to be sub and store into object. - * @param order a type of Atomic_Order. - * - * @retval a result value before sub ops. - */ -static inline unsigned int _Atomic_Fetch_sub_uint( - volatile Atomic_Uint *object, - unsigned int value, - Atomic_Order order -) -{ - return _CPU_atomic_Fetch_sub_uint( object, value, order ); -} - -static inline unsigned long _Atomic_Fetch_sub_ulong( - volatile Atomic_Ulong *object, - unsigned long value, - Atomic_Order order -) -{ - return _CPU_atomic_Fetch_sub_ulong( object, value, order ); -} - -static inline uintptr_t _Atomic_Fetch_sub_ptr( - volatile Atomic_Pointer *object, - uintptr_t value, - Atomic_Order order -) -{ - return _CPU_atomic_Fetch_sub_ptr( object, value, order ); -} +#define _Atomic_Load_ulong( obj, order ) \ + _CPU_atomic_Load_ulong( obj, order ) -/** - * @brief Atomically load-or-store an atomic type value into object - * - * @param object a atomic type pointer of object. - * @param value a value to be or and store into object. - * @param order a type of Atomic_Order. - * - * @retval a result value before or ops. - */ -static inline unsigned int _Atomic_Fetch_or_uint( - volatile Atomic_Uint *object, - unsigned int value, - Atomic_Order order -) -{ - return _CPU_atomic_Fetch_or_uint( object, value, order ); -} - -static inline unsigned long _Atomic_Fetch_or_ulong( - volatile Atomic_Ulong *object, - unsigned long value, - Atomic_Order order -) -{ - return _CPU_atomic_Fetch_or_ulong( object, value, order ); -} - -static inline uintptr_t _Atomic_Fetch_or_ptr( - volatile Atomic_Pointer *object, - uintptr_t value, - Atomic_Order order -) -{ - return _CPU_atomic_Fetch_or_ptr( object, value, order ); -} +#define _Atomic_Load_ptr( obj, order ) \ + _CPU_atomic_Load_ptr( obj, order ) -/** - * @brief Atomically load-and-store an atomic type value into object - * - * @param object a atomic type pointer of object. - * @param value a value to be and and store into object. - * @param order a type of Atomic_Order. - * - * @retval a result value before and ops. - */ -static inline unsigned int _Atomic_Fetch_and_uint( - volatile Atomic_Uint *object, - unsigned int value, - Atomic_Order order -) -{ - return _CPU_atomic_Fetch_and_uint( object, value, order ); -} - -static inline unsigned long _Atomic_Fetch_and_ulong( - volatile Atomic_Ulong *object, - unsigned long value, - Atomic_Order order -) -{ - return _CPU_atomic_Fetch_and_ulong( object, value, order ); -} - -static inline uintptr_t _Atomic_Fetch_and_ptr( - volatile Atomic_Pointer *object, - uintptr_t value, - Atomic_Order order -) -{ - return _CPU_atomic_Fetch_and_ptr( object, value, order ); -} +#define _Atomic_Store_uint( obj, desr, order ) \ + _CPU_atomic_Store_uint( obj, desr, order ) -/** - * @brief Atomically exchange an atomic type value into object - * - * @param object a atomic type pointer of object. - * @param value a value to exchange and and store into object. - * @param order a type of Atomic_Order. - * - * @retval a result value before exchange ops. - */ -static inline unsigned int _Atomic_Exchange_uint( - volatile Atomic_Uint *object, - unsigned int value, - Atomic_Order order -) -{ - return _CPU_atomic_Exchange_uint( object, value, order ); -} - -static inline unsigned long _Atomic_Exchange_ulong( - volatile Atomic_Ulong *object, - unsigned long value, - Atomic_Order order -) -{ - return _CPU_atomic_Exchange_ulong( object, value, order ); -} - -static inline void *_Atomic_Exchange_ptr( - volatile Atomic_Pointer *object, - void *pointer, - Atomic_Order order -) -{ - return _CPU_atomic_Exchange_ptr( object, pointer, order ); -} +#define _Atomic_Store_ulong( obj, desr, order ) \ + _CPU_atomic_Store_ulong( obj, desr, order ) -/** - * @brief Atomically compare the value stored at object with a - * old_value and if the two values are equal, update the value of a - * address with a new_value - * - * @param object a atomic type pointer of object. - * @param old_value pointer of a value. - * @param new_value a atomic type value. - * @param order_succ a type of Atomic_Order for successful exchange. - * @param order_fail a type of Atomic_Order for failed exchange. - * - * @retval true if the compare exchange successully. - * @retval false if the compare exchange failed. - */ -static inline bool _Atomic_Compare_exchange_uint( - volatile Atomic_Uint *object, - unsigned int *old_value, - unsigned int new_value, - Atomic_Order order_succ, - Atomic_Order order_fail -) -{ - return _CPU_atomic_Compare_exchange_uint( object, old_value, new_value, - order_succ, order_fail ); -} - -static inline bool _Atomic_Compare_exchange_ulong( - volatile Atomic_Ulong *object, - unsigned long *old_value, - unsigned long new_value, - Atomic_Order order_succ, - Atomic_Order order_fail -) -{ - return _CPU_atomic_Compare_exchange_ulong( object, old_value, new_value, - order_succ, order_fail ); -} - -static inline bool _Atomic_Compare_exchange_ptr( - volatile Atomic_Pointer *object, - void **old_pointer, - void *new_pointer, - Atomic_Order order_succ, - Atomic_Order order_fail -) -{ - return _CPU_atomic_Compare_exchange_ptr( object, old_pointer, new_pointer, - order_succ, order_fail ); -} +#define _Atomic_Store_ptr( obj, desr, order ) \ + _CPU_atomic_Store_ptr( obj, desr, order ) -/** - * @brief Atomically clears an atomic flag. - * - * @param[in, out] object Pointer to the atomic flag object. - * @param[in] order The atomic memory order. - * - */ -static inline void _Atomic_Flag_clear( - volatile Atomic_Flag *object, - Atomic_Order order -) -{ - _CPU_atomic_Flag_clear( object, order ); -} +#define _Atomic_Fetch_add_uint( obj, arg, order ) \ + _CPU_atomic_Fetch_add_uint( obj, arg, order ) -/** - * @brief Atomically tests and sets an atomic flag. - * - * @param[in, out] object Pointer to the atomic flag object. - * @param[in] order The atomic memory order. - * - * @retval true The atomic flag was already set. - * @retval false Otherwise. - */ -static inline bool _Atomic_Flag_test_and_set( - volatile Atomic_Flag *object, - Atomic_Order order -) -{ - return _CPU_atomic_Flag_test_and_set( object, order ); -} - -#ifdef __cplusplus -} -#endif - -/**@}*/ -#endif -/* end of include file */ +#define _Atomic_Fetch_add_ulong( obj, arg, order ) \ + _CPU_atomic_Fetch_add_ulong( obj, arg, order ) + +#define _Atomic_Fetch_add_ptr( obj, arg, order ) \ + _CPU_atomic_Fetch_add_ptr( obj, arg, order ) + +#define _Atomic_Fetch_sub_uint( obj, arg, order ) \ + _CPU_atomic_Fetch_sub_uint( obj, arg, order ) + +#define _Atomic_Fetch_sub_ulong( obj, arg, order ) \ + _CPU_atomic_Fetch_sub_ulong( obj, arg, order ) + +#define _Atomic_Fetch_sub_ptr( obj, arg, order ) \ + _CPU_atomic_Fetch_sub_ptr( obj, arg, order ) + +#define _Atomic_Fetch_or_uint( obj, arg, order ) \ + _CPU_atomic_Fetch_or_uint( obj, arg, order ) + +#define _Atomic_Fetch_or_ulong( obj, arg, order ) \ + _CPU_atomic_Fetch_or_ulong( obj, arg, order ) + +#define _Atomic_Fetch_or_ptr( obj, arg, order ) \ + _CPU_atomic_Fetch_or_ptr( obj, arg, order ) + +#define _Atomic_Fetch_and_uint( obj, arg, order ) \ + _CPU_atomic_Fetch_and_uint( obj, arg, order ) + +#define _Atomic_Fetch_and_ulong( obj, arg, order ) \ + _CPU_atomic_Fetch_and_ulong( obj, arg, order ) + +#define _Atomic_Fetch_and_ptr( obj, arg, order ) \ + _CPU_atomic_Fetch_and_ptr( obj, arg, order ) + +#define _Atomic_Exchange_uint( obj, desr, order ) \ + _CPU_atomic_Exchange_uint( obj, desr, order ) + +#define _Atomic_Exchange_ulong( obj, desr, order ) \ + _CPU_atomic_Exchange_ulong( obj, desr, order ) + +#define _Atomic_Exchange_ptr( obj, desr, order ) \ + _CPU_atomic_Exchange_ptr( obj, desr, order ) + +#define _Atomic_Compare_exchange_uint( obj, expected, desired, succ, fail ) \ + _CPU_atomic_Compare_exchange_uint( obj, expected, desired, succ, fail ) + +#define _Atomic_Compare_exchange_ulong( obj, expected, desired, succ, fail ) \ + _CPU_atomic_Compare_exchange_ulong( obj, expected, desired, succ, fail ) + +#define _Atomic_Compare_exchange_ptr( obj, expected, desired, succ, fail ) \ + _CPU_atomic_Compare_exchange_ptr( obj, expected, desired, succ, fail ) + +#define _Atomic_Flag_clear( obj, order ) \ + _CPU_atomic_Flag_clear( obj, order ) + +#define _Atomic_Flag_test_and_set( obj, order ) \ + _CPU_atomic_Flag_test_and_set( obj, order ) + +/** @} */ + +#endif /* _RTEMS_SCORE_ATOMIC_H */ diff --git a/cpukit/score/include/rtems/score/cpustdatomic.h b/cpukit/score/include/rtems/score/cpustdatomic.h index a663a06293..a9b8eaeb36 100644 --- a/cpukit/score/include/rtems/score/cpustdatomic.h +++ b/cpukit/score/include/rtems/score/cpustdatomic.h @@ -1,10 +1,7 @@ /** - * @file rtems/score/cpustdatomic.h + * @file * - * This include file defines the generic data struct and implementation - * based on stdatomic.h for all the support architectures. You should not - * include this header file directly, because it will be used by atomic.h - * which should be included by score components + * @brief Atomic Operations CPU API */ /* @@ -15,424 +12,256 @@ * http://www.rtems.org/license/LICENSE. */ -#ifndef _RTEMS_SCORE_GENERAL_STDATOMIC_CPU_H_ -#define _RTEMS_SCORE_GENERAL_STDATOMIC_CPU_H_ +#ifndef _RTEMS_SCORE_CPUSTDATOMIC_H +#define _RTEMS_SCORE_CPUSTDATOMIC_H -#include <stdatomic.h> -#include <stdbool.h> #include <stdint.h> -#ifdef __cplusplus -extern "C" { -#endif +#if defined(__cplusplus) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 9 -/** - * @defgroup RTEMS general stdatomic data type and implementation. +/* + * The GCC 4.9 ships its own <stdatomic.h> which is not C++ compatible. The + * suggested solution was to include <atomic> in case C++ is used. This works + * at least with GCC 4.9. See also: * + * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60932 + * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60940 */ -/**@{*/ +#include <atomic> -/** - * @brief atomic operation unsigned integer type - */ -typedef atomic_uint Atomic_Uint; +typedef std::atomic_uint CPU_atomic_Uint; -/** - * @brief atomic operation unsigned long integer type - */ -typedef atomic_ulong Atomic_Ulong; +typedef std::atomic_ulong CPU_atomic_Ulong; -/** - * @brief atomic operation unsigned integer the size of a pointer type - */ -typedef atomic_uintptr_t Atomic_Pointer; +typedef std::atomic_uintptr_t CPU_atomic_Pointer; -/** - * @brief atomic operation flag type - */ -typedef atomic_flag Atomic_Flag; +typedef std::atomic_flag CPU_atomic_Flag; -/** - * @brief Memory order according to ISO/IEC 9899:2011. - */ -typedef enum { - ATOMIC_ORDER_RELAXED = memory_order_relaxed, - ATOMIC_ORDER_ACQUIRE = memory_order_acquire, - ATOMIC_ORDER_RELEASE = memory_order_release, - ATOMIC_ORDER_SEQ_CST = memory_order_seq_cst -} Atomic_Order; +#define CPU_ATOMIC_ORDER_RELAXED std::memory_order_relaxed +#define CPU_ATOMIC_ORDER_ACQUIRE std::memory_order_acquire -/** - * @brief atomic data initializer for static initialization. - */ -#define CPU_ATOMIC_INITIALIZER_UINT(value) ATOMIC_VAR_INIT(value) -#define CPU_ATOMIC_INITIALIZER_ULONG(value) ATOMIC_VAR_INIT(value) -#define CPU_ATOMIC_INITIALIZER_PTR(pointer) \ - ATOMIC_VAR_INIT((uintptr_t) pointer) +#define CPU_ATOMIC_ORDER_RELEASE std::memory_order_release + +#define CPU_ATOMIC_ORDER_SEQ_CST std::memory_order_seq_cst + +#define CPU_ATOMIC_INITIALIZER_UINT( value ) ATOMIC_VAR_INIT( value ) + +#define CPU_ATOMIC_INITIALIZER_ULONG( value ) ATOMIC_VAR_INIT( value ) + +#define CPU_ATOMIC_INITIALIZER_PTR( value ) \ + ATOMIC_VAR_INIT( (uintptr_t) (value) ) #define CPU_ATOMIC_INITIALIZER_FLAG ATOMIC_FLAG_INIT -static inline void _CPU_atomic_Fence( - Atomic_Order order -) -{ - atomic_thread_fence( (memory_order) order ); -} +#define _CPU_atomic_Fence( order ) atomic_thread_fence( order ) -/** - * @brief Initializes an atomic type value into a atomic object. - * - * @param object an atomic type pointer of object. - * @param value a value to be stored into object. - */ -static inline void _CPU_atomic_Init_uint( - volatile Atomic_Uint *object, - unsigned int value -) -{ - atomic_init( object, value ); -} - -static inline void _CPU_atomic_Init_ulong( - volatile Atomic_Ulong *object, - unsigned long value -) -{ - atomic_init( object, value ); -} - -static inline void _CPU_atomic_Init_ptr( - volatile Atomic_Pointer *object, - void *pointer -) -{ - atomic_init( object, (uintptr_t) pointer ); -} +#define _CPU_atomic_Init_uint( obj, desired ) \ + (obj)->store( desired ) -/** - * @brief Atomically load an atomic type value from atomic object. - * - * @param object an atomic type pointer of object. - * @param order a type of Atomic_Order. - * - * The order shall not be ATOMIC_ORDER_RELEASE. - */ -static inline unsigned int _CPU_atomic_Load_uint( - volatile Atomic_Uint *object, - Atomic_Order order -) -{ - return atomic_load_explicit( object, (memory_order) order ); -} - -static inline unsigned long _CPU_atomic_Load_ulong( - volatile Atomic_Ulong *object, - Atomic_Order order -) -{ - return atomic_load_explicit( object, (memory_order) order ); -} - -static inline void *_CPU_atomic_Load_ptr( - volatile Atomic_Pointer *object, - Atomic_Order order -) -{ - return (void *) atomic_load_explicit( object, (memory_order) order ); -} +#define _CPU_atomic_Init_ulong( obj, desired ) \ + (obj)->store( desired ) -/** - * @brief Atomically store an atomic type value into a atomic object. - * - * @param object an atomic type pointer of object. - * @param value a value to be stored into object. - * @param order a type of Atomic_Order. - * - * The order shall not be ATOMIC_ORDER_ACQUIRE. - */ -static inline void _CPU_atomic_Store_uint( - volatile Atomic_Uint *object, - unsigned int value, - Atomic_Order order -) -{ - atomic_store_explicit( object, value, (memory_order) order ); -} - -static inline void _CPU_atomic_Store_ulong( - volatile Atomic_Ulong *object, - unsigned long value, - Atomic_Order order -) -{ - atomic_store_explicit( object, value, (memory_order) order ); -} - -static inline void _CPU_atomic_Store_ptr( - volatile Atomic_Pointer *object, - void *pointer, - Atomic_Order order -) -{ - atomic_store_explicit( object, pointer, (memory_order) order ); -} +#define _CPU_atomic_Init_ptr( obj, desired ) \ + (obj)->store( desired ) -/** - * @brief Atomically load-add-store an atomic type value into object - * - * @param object a atomic type pointer of object. - * @param value a value to be add and store into object. - * @param order a type of Atomic_Order. - * - * @retval a result value before add ops. - */ -static inline unsigned int _CPU_atomic_Fetch_add_uint( - volatile Atomic_Uint *object, - unsigned int value, - Atomic_Order order -) -{ - return atomic_fetch_add_explicit( object, value, (memory_order) order ); -} - -static inline unsigned long _CPU_atomic_Fetch_add_ulong( - volatile Atomic_Ulong *object, - unsigned long value, - Atomic_Order order -) -{ - return atomic_fetch_add_explicit( object, value, (memory_order) order ); -} - -static inline uintptr_t _CPU_atomic_Fetch_add_ptr( - volatile Atomic_Pointer *object, - uintptr_t value, - Atomic_Order order -) -{ - return atomic_fetch_add_explicit( object, value, (memory_order) order ); -} +#define _CPU_atomic_Load_uint( obj, order ) \ + (obj)->load( order ) -/** - * @brief Atomically load-sub-store an atomic type value into object - * - * @param object a atomic type pointer of object. - * @param value a value to be sub and store into object. - * @param order a type of Atomic_Order. - * - * @retval a result value before sub ops. - */ -static inline unsigned int _CPU_atomic_Fetch_sub_uint( - volatile Atomic_Uint *object, - unsigned int value, - Atomic_Order order -) -{ - return atomic_fetch_sub_explicit( object, value, (memory_order) order ); -} - -static inline unsigned long _CPU_atomic_Fetch_sub_ulong( - volatile Atomic_Ulong *object, - unsigned long value, - Atomic_Order order -) -{ - return atomic_fetch_sub_explicit( object, value, (memory_order) order ); -} - -static inline uintptr_t _CPU_atomic_Fetch_sub_ptr( - volatile Atomic_Pointer *object, - uintptr_t value, - Atomic_Order order -) -{ - return atomic_fetch_sub_explicit( object, value, (memory_order) order ); -} +#define _CPU_atomic_Load_ulong( obj, order ) \ + (obj)->load( order ) -/** - * @brief Atomically load-or-store an atomic type value into object - * - * @param object a atomic type pointer of object. - * @param value a value to be or and store into object. - * @param order a type of Atomic_Order. - * - * @retval a result value before or ops. - */ -static inline unsigned int _CPU_atomic_Fetch_or_uint( - volatile Atomic_Uint *object, - unsigned int value, - Atomic_Order order -) -{ - return atomic_fetch_or_explicit( object, value, (memory_order) order ); -} - -static inline unsigned long _CPU_atomic_Fetch_or_ulong( - volatile Atomic_Ulong *object, - unsigned long value, - Atomic_Order order -) -{ - return atomic_fetch_or_explicit( object, value, (memory_order) order ); -} - -static inline uintptr_t _CPU_atomic_Fetch_or_ptr( - volatile Atomic_Pointer *object, - uintptr_t value, - Atomic_Order order -) -{ - return atomic_fetch_or_explicit( object, value, (memory_order) order ); -} +#define _CPU_atomic_Load_ptr( obj, order ) \ + (void *) (obj)->load( order ) -/** - * @brief Atomically load-and-store an atomic type value into object - * - * @param object a atomic type pointer of object. - * @param value a value to be and and store into object. - * @param order a type of Atomic_Order. - * - * @retval a result value before and ops. - */ -static inline unsigned int _CPU_atomic_Fetch_and_uint( - volatile Atomic_Uint *object, - unsigned int value, - Atomic_Order order -) -{ - return atomic_fetch_and_explicit( object, value, (memory_order) order ); -} - -static inline unsigned long _CPU_atomic_Fetch_and_ulong( - volatile Atomic_Ulong *object, - unsigned long value, - Atomic_Order order -) -{ - return atomic_fetch_and_explicit( object, value, (memory_order) order ); -} - -static inline uintptr_t _CPU_atomic_Fetch_and_ptr( - volatile Atomic_Pointer *object, - uintptr_t value, - Atomic_Order order -) -{ - return atomic_fetch_and_explicit( object, value, (memory_order) order ); -} +#define _CPU_atomic_Store_uint( obj, desr, order ) \ + (obj)->store( desr, order ) -/** - * @brief Atomically exchange an atomic type value into object - * - * @param object a atomic type pointer of object. - * @param value a value to exchange and and store into object. - * @param order a type of Atomic_Order. - * - * @retval a result value before exchange ops. - */ -static inline unsigned int _CPU_atomic_Exchange_uint( - volatile Atomic_Uint *object, - unsigned int value, - Atomic_Order order -) -{ - return atomic_exchange_explicit( object, value, (memory_order) order ); -} - -static inline unsigned long _CPU_atomic_Exchange_ulong( - volatile Atomic_Ulong *object, - unsigned long value, - Atomic_Order order -) -{ - return atomic_exchange_explicit( object, value, (memory_order) order ); -} - -static inline void *_CPU_atomic_Exchange_ptr( - volatile Atomic_Pointer *object, - void *pointer, - Atomic_Order order -) -{ - return (void *) atomic_exchange_explicit( - object, - (uintptr_t) pointer, - (memory_order) order - ); -} +#define _CPU_atomic_Store_ulong( obj, desr, order ) \ + (obj)->store( desr, order ) -/** - * @brief Atomically compare the value stored at object with a - * old_value and if the two values are equal, update the value of a - * address with a new_value - * - * @param object a atomic type pointer of object. - * @param old_value pointer of a value. - * @param new_value a atomic type value. - * @param order_succ a type of Atomic_Order for successful exchange. - * @param order_fail a type of Atomic_Order for failed exchange. - * - * @retval true if the compare exchange successully. - * @retval false if the compare exchange failed. - */ -static inline bool _CPU_atomic_Compare_exchange_uint( - volatile Atomic_Uint *object, - unsigned int *old_value, - unsigned int new_value, - Atomic_Order order_succ, - Atomic_Order order_fail -) -{ - return atomic_compare_exchange_strong_explicit( object, old_value, - new_value, order_succ, order_fail ); -} - -static inline bool _CPU_atomic_Compare_exchange_ulong( - volatile Atomic_Ulong *object, - unsigned long *old_value, - unsigned long new_value, - Atomic_Order order_succ, - Atomic_Order order_fail -) -{ - return atomic_compare_exchange_strong_explicit( object, old_value, - new_value, order_succ, order_fail ); -} - -static inline bool _CPU_atomic_Compare_exchange_ptr( - volatile Atomic_Pointer *object, - void **old_pointer, - void *new_pointer, - Atomic_Order order_succ, - Atomic_Order order_fail -) -{ - return atomic_compare_exchange_strong_explicit( object, old_pointer, - new_pointer, order_succ, order_fail ); -} - -static inline void _CPU_atomic_Flag_clear( - volatile Atomic_Flag *object, - Atomic_Order order -) -{ - return atomic_flag_clear_explicit( object, (memory_order) order ); -} - -static inline bool _CPU_atomic_Flag_test_and_set( - volatile Atomic_Flag *object, - Atomic_Order order -) -{ - return atomic_flag_test_and_set_explicit( object, (memory_order) order ); -} - -#ifdef __cplusplus -} -#endif - -/**@}*/ -#endif -/* end of include file */ +#define _CPU_atomic_Store_ptr( obj, desr, order ) \ + (obj)->store( (uintptr_t) desr, order ) + +#define _CPU_atomic_Fetch_add_uint( obj, arg, order ) \ + (obj)->fetch_add( arg, order ) + +#define _CPU_atomic_Fetch_add_ulong( obj, arg, order ) \ + (obj)->fetch_add( arg, order ) + +#define _CPU_atomic_Fetch_add_ptr( obj, arg, order ) \ + (obj)->fetch_add( arg, (uintptr_t) order ) + +#define _CPU_atomic_Fetch_sub_uint( obj, arg, order ) \ + (obj)->fetch_sub( arg, order ) + +#define _CPU_atomic_Fetch_sub_ulong( obj, arg, order ) \ + (obj)->fetch_sub( arg, order ) + +#define _CPU_atomic_Fetch_sub_ptr( obj, arg, order ) \ + (obj)->fetch_sub( arg, (uintptr_t) order ) + +#define _CPU_atomic_Fetch_or_uint( obj, arg, order ) \ + (obj)->fetch_or( arg, order ) + +#define _CPU_atomic_Fetch_or_ulong( obj, arg, order ) \ + (obj)->fetch_or( arg, order ) + +#define _CPU_atomic_Fetch_or_ptr( obj, arg, order ) \ + (obj)->fetch_or( arg, (uintptr_t) order ) + +#define _CPU_atomic_Fetch_and_uint( obj, arg, order ) \ + (obj)->fetch_and( arg, order ) + +#define _CPU_atomic_Fetch_and_ulong( obj, arg, order ) \ + (obj)->fetch_and( arg, order ) + +#define _CPU_atomic_Fetch_and_ptr( obj, arg, order ) \ + (obj)->fetch_and( arg, (uintptr_t) order ) + +#define _CPU_atomic_Exchange_uint( obj, desr, order ) \ + (obj)->exchange( desr, order ) + +#define _CPU_atomic_Exchange_ulong( obj, desr, order ) \ + (obj)->exchange( desr, order ) + +#define _CPU_atomic_Exchange_ptr( obj, desr, order ) \ + (void *) (obj)->exchange( desr, (uintptr_t) order ) + +#define _CPU_atomic_Compare_exchange_uint( obj, expected, desired, succ, fail ) \ + (obj)->compare_exchange_strong( expected, desired, succ, fail ) + +#define _CPU_atomic_Compare_exchange_ulong( obj, expected, desired, succ, fail ) \ + (obj)->compare_exchange_strong( expected, desired, succ, fail ) + +#define _CPU_atomic_Compare_exchange_ptr( obj, expected, desired, succ, fail ) \ + (obj)->compare_exchange_strong( (void **) expected, (uintptr_t) desired, succ, fail ) + +#define _CPU_atomic_Flag_clear( obj, order ) \ + (obj)->clear( order ) + +#define _CPU_atomic_Flag_test_and_set( obj, order ) \ + (obj)->test_and_set( order ) + +#else /* __cplusplus */ + +#include <stdatomic.h> + +typedef atomic_uint CPU_atomic_Uint; + +typedef atomic_ulong CPU_atomic_Ulong; + +typedef atomic_uintptr_t CPU_atomic_Pointer; + +typedef atomic_flag CPU_atomic_Flag; + +#define CPU_ATOMIC_ORDER_RELAXED memory_order_relaxed + +#define CPU_ATOMIC_ORDER_ACQUIRE memory_order_acquire + +#define CPU_ATOMIC_ORDER_RELEASE memory_order_release + +#define CPU_ATOMIC_ORDER_SEQ_CST memory_order_seq_cst + +#define CPU_ATOMIC_INITIALIZER_UINT( value ) ATOMIC_VAR_INIT( value ) + +#define CPU_ATOMIC_INITIALIZER_ULONG( value ) ATOMIC_VAR_INIT( value ) + +#define CPU_ATOMIC_INITIALIZER_PTR( value ) \ + ATOMIC_VAR_INIT( (uintptr_t) (value) ) + +#define CPU_ATOMIC_INITIALIZER_FLAG ATOMIC_FLAG_INIT + +#define _CPU_atomic_Fence( order ) atomic_thread_fence( order ) + +#define _CPU_atomic_Init_uint( obj, desired ) \ + atomic_init( obj, desired ) + +#define _CPU_atomic_Init_ulong( obj, desired ) \ + atomic_init( obj, desired ) + +#define _CPU_atomic_Init_ptr( obj, desired ) \ + atomic_init( obj, (uintptr_t) desired ) + +#define _CPU_atomic_Load_uint( obj, order ) \ + atomic_load_explicit( obj, order ) + +#define _CPU_atomic_Load_ulong( obj, order ) \ + atomic_load_explicit( obj, order ) + +#define _CPU_atomic_Load_ptr( obj, order ) \ + (void *) atomic_load_explicit( obj, order ) + +#define _CPU_atomic_Store_uint( obj, desr, order ) \ + atomic_store_explicit( obj, desr, order ) + +#define _CPU_atomic_Store_ulong( obj, desr, order ) \ + atomic_store_explicit( obj, desr, order ) + +#define _CPU_atomic_Store_ptr( obj, desr, order ) \ + atomic_store_explicit( obj, desr, order ) + +#define _CPU_atomic_Fetch_add_uint( obj, arg, order ) \ + atomic_fetch_add_explicit( obj, arg, order ) + +#define _CPU_atomic_Fetch_add_ulong( obj, arg, order ) \ + atomic_fetch_add_explicit( obj, arg, order ) + +#define _CPU_atomic_Fetch_add_ptr( obj, arg, order ) \ + atomic_fetch_add_explicit( obj, arg, order ) + +#define _CPU_atomic_Fetch_sub_uint( obj, arg, order ) \ + atomic_fetch_sub_explicit( obj, arg, order ) + +#define _CPU_atomic_Fetch_sub_ulong( obj, arg, order ) \ + atomic_fetch_sub_explicit( obj, arg, order ) + +#define _CPU_atomic_Fetch_sub_ptr( obj, arg, order ) \ + atomic_fetch_sub_explicit( obj, arg, order ) + +#define _CPU_atomic_Fetch_or_uint( obj, arg, order ) \ + atomic_fetch_or_explicit( obj, arg, order ) + +#define _CPU_atomic_Fetch_or_ulong( obj, arg, order ) \ + atomic_fetch_or_explicit( obj, arg, order ) + +#define _CPU_atomic_Fetch_or_ptr( obj, arg, order ) \ + atomic_fetch_or_explicit( obj, arg, order ) + +#define _CPU_atomic_Fetch_and_uint( obj, arg, order ) \ + atomic_fetch_and_explicit( obj, arg, order ) + +#define _CPU_atomic_Fetch_and_ulong( obj, arg, order ) \ + atomic_fetch_and_explicit( obj, arg, order ) + +#define _CPU_atomic_Fetch_and_ptr( obj, arg, order ) \ + atomic_fetch_and_explicit( obj, arg, order ) + +#define _CPU_atomic_Exchange_uint( obj, desr, order ) \ + atomic_exchange_explicit( obj, desr, order ) + +#define _CPU_atomic_Exchange_ulong( obj, desr, order ) \ + atomic_exchange_explicit( obj, desr, order ) + +#define _CPU_atomic_Exchange_ptr( obj, desr, order ) \ + atomic_exchange_explicit( obj, desr, order ) + +#define _CPU_atomic_Compare_exchange_uint( obj, expected, desired, succ, fail ) \ + atomic_compare_exchange_strong_explicit( obj, expected, desired, succ, fail ) + +#define _CPU_atomic_Compare_exchange_ulong( obj, expected, desired, succ, fail ) \ + atomic_compare_exchange_strong_explicit( obj, expected, desired, succ, fail ) + +#define _CPU_atomic_Compare_exchange_ptr( obj, expected, desired, succ, fail ) \ + atomic_compare_exchange_strong_explicit( obj, expected, desired, succ, fail ) + +#define _CPU_atomic_Flag_clear( obj, order ) \ + atomic_flag_clear_explicit( obj, order ) + +#define _CPU_atomic_Flag_test_and_set( obj, order ) \ + atomic_flag_test_and_set_explicit( obj, order ) + +#endif /* __cplusplus */ + +#endif /* _RTEMS_SCORE_CPUSTDATOMIC_H */ |