[PATCH 1/2] score: Workaround for GCC 4.9 for atomic ops

Sebastian Huber sebastian.huber at embedded-brains.de
Thu Jun 26 11:33:37 UTC 2014


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
---
 cpukit/score/include/rtems/score/atomic.h       |  461 ++++--------------
 cpukit/score/include/rtems/score/cpustdatomic.h |  585 ++++++++---------------
 2 files changed, 304 insertions(+), 742 deletions(-)

diff --git a/cpukit/score/include/rtems/score/atomic.h b/cpukit/score/include/rtems/score/atomic.h
index da5b48d..0cbe577 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);
-}
+#define _Atomic_Init_uint( obj, desired ) \
+  _CPU_atomic_Init_uint( obj, desired )
 
-static inline void _Atomic_Init_ulong(
-  volatile Atomic_Ulong *object,
-  unsigned long value
-)
-{
-  _CPU_atomic_Init_ulong(object, value);
-}
+#define _Atomic_Init_ulong( obj, desired ) \
+  _CPU_atomic_Init_ulong( obj, desired )
 
-static inline void _Atomic_Init_ptr(
-  volatile Atomic_Pointer *object,
-  void *pointer
-)
-{
-  _CPU_atomic_Init_ptr(object, pointer);
-}
+#define _Atomic_Init_ptr( obj, desired ) \
+  _CPU_atomic_Init_ptr( 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 );
-}
+#define _Atomic_Load_uint( obj, order ) \
+  _CPU_atomic_Load_uint( obj, order )
 
-static inline unsigned long _Atomic_Load_ulong(
-  volatile Atomic_Ulong *object,
-  Atomic_Order order
-)
-{
-  return _CPU_atomic_Load_ulong( object, order );
-}
+#define _Atomic_Load_ulong( obj, order ) \
+  _CPU_atomic_Load_ulong( obj, order )
 
-static inline void *_Atomic_Load_ptr(
-  volatile Atomic_Pointer *object,
-  Atomic_Order order
-)
-{
-  return _CPU_atomic_Load_ptr( object, order );
-}
+#define _Atomic_Load_ptr( obj, order ) \
+  _CPU_atomic_Load_ptr( obj, order )
 
-/**
- * @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 );
-}
+#define _Atomic_Store_uint( obj, desr, order ) \
+  _CPU_atomic_Store_uint( obj, desr, order )
 
-static inline void _Atomic_Store_ulong(
-  volatile Atomic_Ulong *object,
-  unsigned long value,
-  Atomic_Order order
-)
-{
-  _CPU_atomic_Store_ulong( object, value, order );
-}
+#define _Atomic_Store_ulong( obj, desr, order ) \
+  _CPU_atomic_Store_ulong( obj, desr, 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_Store_ptr( obj, desr, order ) \
+  _CPU_atomic_Store_ptr( obj, desr, order )
 
-/**
- * @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 );
-}
+#define _Atomic_Fetch_add_uint( obj, arg, order ) \
+  _CPU_atomic_Fetch_add_uint( obj, arg, 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 );
-}
+#define _Atomic_Fetch_add_ulong( obj, arg, order ) \
+  _CPU_atomic_Fetch_add_ulong( obj, arg, 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_Fetch_add_ptr( obj, arg, order ) \
+  _CPU_atomic_Fetch_add_ptr( obj, arg, 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 );
-}
+#define _Atomic_Fetch_sub_uint( obj, arg, order ) \
+  _CPU_atomic_Fetch_sub_uint( obj, arg, 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 );
-}
+#define _Atomic_Fetch_sub_ulong( obj, arg, order ) \
+  _CPU_atomic_Fetch_sub_ulong( obj, arg, 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_Fetch_sub_ptr( obj, arg, order ) \
+  _CPU_atomic_Fetch_sub_ptr( obj, arg, 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 );
-}
+#define _Atomic_Fetch_or_uint( obj, arg, order ) \
+  _CPU_atomic_Fetch_or_uint( obj, arg, 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 );
-}
+#define _Atomic_Fetch_or_ulong( obj, arg, order ) \
+  _CPU_atomic_Fetch_or_ulong( obj, arg, 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_Fetch_or_ptr( obj, arg, order ) \
+  _CPU_atomic_Fetch_or_ptr( obj, arg, 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 );
-}
+#define _Atomic_Fetch_and_uint( obj, arg, order ) \
+  _CPU_atomic_Fetch_and_uint( obj, arg, 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 );
-}
+#define _Atomic_Fetch_and_ulong( obj, arg, order ) \
+  _CPU_atomic_Fetch_add_ulong( obj, arg, 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_Fetch_and_ptr( obj, arg, order ) \
+  _CPU_atomic_Fetch_and_ptr( obj, arg, 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 );
-}
+#define _Atomic_Exchange_uint( obj, desr, order ) \
+  _CPU_atomic_Exchange_uint( obj, desr, 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 );
-}
+#define _Atomic_Exchange_ulong( obj, desr, order ) \
+  _CPU_atomic_Fetch_add_ulong( obj, desr, 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_Exchange_ptr( obj, desr, order ) \
+  _CPU_atomic_Exchange_ptr( 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 );
-}
+#define _Atomic_Compare_exchange_uint( obj, expected, desired, succ, fail ) \
+  _CPU_atomic_Compare_exchange_uint( obj, expected, desired, succ, 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 );
-}
+#define _Atomic_Compare_exchange_ulong( obj, expected, desired, succ, fail ) \
+  _CPU_atomic_Compare_exchange_ulong( obj, expected, desired, succ, 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_Compare_exchange_ptr( obj, expected, desired, succ, fail ) \
+  _CPU_atomic_Compare_exchange_ptr( obj, expected, desired, succ, fail )
 
-/**
- * @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_Flag_clear( obj, order ) \
+  _CPU_atomic_Flag_clear( obj, 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 );
-}
+#define _Atomic_Flag_test_and_set( obj, order ) \
+  _CPU_atomic_Flag_test_and_set( obj, order )
 
-#ifdef __cplusplus
-}
-#endif
+/** @} */
 
-/**@}*/
-#endif
-/*  end of include file */
+#endif /* _RTEMS_SCORE_ATOMIC_H */
diff --git a/cpukit/score/include/rtems/score/cpustdatomic.h b/cpukit/score/include/rtems/score/cpustdatomic.h
index a663a06..a9b8eae 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 );
-}
+#define _CPU_atomic_Init_uint( obj, desired ) \
+  (obj)->store( desired )
 
-static inline void _CPU_atomic_Init_ulong(
-  volatile Atomic_Ulong *object,
-  unsigned long value
-)
-{
-  atomic_init( object, value );
-}
+#define _CPU_atomic_Init_ulong( obj, desired ) \
+  (obj)->store( desired )
 
-static inline void _CPU_atomic_Init_ptr(
-  volatile Atomic_Pointer *object,
-  void *pointer
-)
-{
-  atomic_init( object, (uintptr_t) pointer );
-}
+#define _CPU_atomic_Init_ptr( 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 );
-}
+#define _CPU_atomic_Load_uint( obj, order ) \
+  (obj)->load( order )
 
-static inline unsigned long _CPU_atomic_Load_ulong(
-  volatile Atomic_Ulong *object,
-  Atomic_Order order
-)
-{
-  return atomic_load_explicit( object, (memory_order) order );
-}
+#define _CPU_atomic_Load_ulong( obj, order ) \
+  (obj)->load( 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_Load_ptr( obj, order ) \
+  (void *) (obj)->load( order )
 
-/**
- * @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 );
-}
+#define _CPU_atomic_Store_uint( obj, desr, order ) \
+  (obj)->store( desr, 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 );
-}
+#define _CPU_atomic_Store_ulong( obj, desr, order ) \
+  (obj)->store( desr, 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_Store_ptr( obj, desr, order ) \
+  (obj)->store( (uintptr_t) desr, order )
 
-/**
- * @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 );
-}
+#define _CPU_atomic_Fetch_add_uint( obj, arg, order ) \
+  (obj)->fetch_add( arg, 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 );
-}
+#define _CPU_atomic_Fetch_add_ulong( obj, arg, order ) \
+  (obj)->fetch_add( arg, 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_Fetch_add_ptr( obj, arg, order ) \
+  (obj)->fetch_add( arg, (uintptr_t) 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 );
-}
+#define _CPU_atomic_Fetch_sub_uint( obj, arg, order ) \
+  (obj)->fetch_sub( arg, 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 );
-}
+#define _CPU_atomic_Fetch_sub_ulong( obj, arg, order ) \
+  (obj)->fetch_sub( arg, 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_Fetch_sub_ptr( obj, arg, order ) \
+  (obj)->fetch_sub( arg, (uintptr_t) 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 );
-}
+#define _CPU_atomic_Fetch_or_uint( obj, arg, order ) \
+  (obj)->fetch_or( arg, 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 );
-}
+#define _CPU_atomic_Fetch_or_ulong( obj, arg, order ) \
+  (obj)->fetch_or( arg, 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_Fetch_or_ptr( obj, arg, order ) \
+  (obj)->fetch_or( arg, (uintptr_t) 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 );
-}
+#define _CPU_atomic_Fetch_and_uint( obj, arg, order ) \
+  (obj)->fetch_and( arg, 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 );
-}
+#define _CPU_atomic_Fetch_and_ulong( obj, arg, order ) \
+  (obj)->fetch_and( arg, 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_Fetch_and_ptr( obj, arg, order ) \
+  (obj)->fetch_and( arg, (uintptr_t) 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 );
-}
+#define _CPU_atomic_Exchange_uint( obj, desr, order ) \
+  (obj)->exchange( desr, 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 );
-}
+#define _CPU_atomic_Exchange_ulong( obj, desr, order ) \
+  (obj)->exchange( desr, 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_Exchange_ptr( obj, desr, order ) \
+  (void *) (obj)->exchange( desr, (uintptr_t) 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 );
-}
+#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 )
 
-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 );
-}
+#define _CPU_atomic_Compare_exchange_ulong( obj, expected, desired, succ, fail ) \
+  atomic_compare_exchange_strong_explicit( obj, expected, desired, succ, 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 );
-}
+#define _CPU_atomic_Compare_exchange_ptr( obj, expected, desired, succ, fail ) \
+  atomic_compare_exchange_strong_explicit( obj, expected, desired, succ, fail )
 
-static inline void _CPU_atomic_Flag_clear(
-  volatile Atomic_Flag *object,
-  Atomic_Order order
-)
-{
-  return atomic_flag_clear_explicit( object, (memory_order) order );
-}
+#define _CPU_atomic_Flag_clear( obj, order ) \
+  atomic_flag_clear_explicit( obj, 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 );
-}
+#define _CPU_atomic_Flag_test_and_set( obj, order ) \
+  atomic_flag_test_and_set_explicit( obj, order )
 
-#ifdef __cplusplus
-}
-#endif
+#endif /* __cplusplus */
 
-/**@}*/
-#endif
-/*  end of include file */
+#endif /* _RTEMS_SCORE_CPUSTDATOMIC_H */
-- 
1.7.7




More information about the devel mailing list