Changeset 89f8eab5 in rtems


Ignore:
Timestamp:
May 7, 2014, 12:55:37 PM (5 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
4.11, master
Children:
dd510a0
Parents:
b42e148
git-author:
Sebastian Huber <sebastian.huber@…> (05/07/14 12:55:37)
git-committer:
Sebastian Huber <sebastian.huber@…> (06/30/14 07:56:23)
Message:

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

Location:
cpukit/score/include/rtems/score
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • cpukit/score/include/rtems/score/atomic.h

    rb42e148 r89f8eab5  
    11/**
    2  * @file  rtems/score/atomic.h
    3  *
    4  * This include file defines the interface for all the atomic
    5  * operations which can be used in the synchronization primitives
    6  * or in the lock-less algorithms. You should not use these API
    7  * in the other components directly.
     2 * @file
     3 *
     4 * @ingroup ScoreAtomic
     5 *
     6 * @brief Atomic Operations API
    87 */
    98
     
    2120#include <rtems/score/cpuatomic.h>
    2221
    23 #ifdef __cplusplus
    24 extern "C" {
    25 #endif
    26 
    2722/**
    28  * @defgroup RTEMS atomic interface
     23 * @defgroup ScoreAtomic Atomic Operations
    2924 *
     25 * @ingroup Score
     26 *
     27 * @brief Support for atomic operations.
     28 *
     29 * Atomic operations can be used to implement low-level synchronization
     30 * primitives on SMP systems, like spin locks.  All atomic operations are
     31 * defined in terms of C11 (ISO/IEC 9899:2011) or C++11 (ISO/IEC 14882:2011).
     32 * For documentation use the standard documents.
     33 *
     34 * @{
    3035 */
    3136
    32 /**@{*/
     37typedef CPU_atomic_Uint Atomic_Uint;
    3338
    34 /**
    35  * @brief atomic data initializer for static initialization.
    36  */
    37 #define ATOMIC_INITIALIZER_UINT(value) CPU_ATOMIC_INITIALIZER_UINT(value)
    38 #define ATOMIC_INITIALIZER_ULONG(value) CPU_ATOMIC_INITIALIZER_ULONG(value)
    39 #define ATOMIC_INITIALIZER_PTR(value) CPU_ATOMIC_INITIALIZER_PTR(value)
     39typedef CPU_atomic_Ulong Atomic_Ulong;
    4040
    41 /**
    42  * @brief Initializes an atomic flag object to the cleared state.
    43  */
     41typedef CPU_atomic_Pointer Atomic_Pointer;
     42
     43typedef CPU_atomic_Flag Atomic_Flag;
     44
     45#define ATOMIC_ORDER_RELAXED CPU_ATOMIC_ORDER_RELAXED
     46
     47#define ATOMIC_ORDER_ACQUIRE CPU_ATOMIC_ORDER_ACQUIRE
     48
     49#define ATOMIC_ORDER_RELEASE CPU_ATOMIC_ORDER_RELEASE
     50
     51#define ATOMIC_ORDER_SEQ_CST CPU_ATOMIC_ORDER_SEQ_CST
     52
     53#define ATOMIC_INITIALIZER_UINT( value ) CPU_ATOMIC_INITIALIZER_UINT( value )
     54
     55#define ATOMIC_INITIALIZER_ULONG( value ) CPU_ATOMIC_INITIALIZER_ULONG( value )
     56
     57#define ATOMIC_INITIALIZER_PTR( value ) CPU_ATOMIC_INITIALIZER_PTR( value )
     58
    4459#define ATOMIC_INITIALIZER_FLAG CPU_ATOMIC_INITIALIZER_FLAG
    4560
    46 static inline void _Atomic_Fence(
    47   Atomic_Order order
    48 )
    49 {
    50   _CPU_atomic_Fence( order );
    51 }
     61#define _Atomic_Fence( order ) _CPU_atomic_Fence( order )
    5262
    53 /**
    54  * @brief Initializes an atomic type value into a atomic object.
    55  *
    56  * @param object an atomic type pointer of object.
    57  * @param pointer a pointer to be stored into object.
    58  */
    59 static inline void _Atomic_Init_uint(
    60   volatile Atomic_Uint *object,
    61   unsigned int value
    62 )
    63 {
    64   _CPU_atomic_Init_uint(object, value);
    65 }
     63#define _Atomic_Init_uint( obj, desired ) \
     64  _CPU_atomic_Init_uint( obj, desired )
    6665
    67 static inline void _Atomic_Init_ulong(
    68   volatile Atomic_Ulong *object,
    69   unsigned long value
    70 )
    71 {
    72   _CPU_atomic_Init_ulong(object, value);
    73 }
     66#define _Atomic_Init_ulong( obj, desired ) \
     67  _CPU_atomic_Init_ulong( obj, desired )
    7468
    75 static inline void _Atomic_Init_ptr(
    76   volatile Atomic_Pointer *object,
    77   void *pointer
    78 )
    79 {
    80   _CPU_atomic_Init_ptr(object, pointer);
    81 }
     69#define _Atomic_Init_ptr( obj, desired ) \
     70  _CPU_atomic_Init_ptr( obj, desired )
    8271
    83 /**
    84  * @brief Atomically load an atomic type value from atomic object.
    85  *
    86  * @param object an atomic type pointer of object.
    87  * @param order a type of Atomic_Order.
    88  *
    89  * The order shall not be ATOMIC_ORDER_RELEASE.
    90  */
    91 static inline unsigned int _Atomic_Load_uint(
    92   volatile Atomic_Uint *object,
    93   Atomic_Order order
    94 )
    95 {
    96   return _CPU_atomic_Load_uint( object, order );
    97 }
     72#define _Atomic_Load_uint( obj, order ) \
     73  _CPU_atomic_Load_uint( obj, order )
    9874
    99 static inline unsigned long _Atomic_Load_ulong(
    100   volatile Atomic_Ulong *object,
    101   Atomic_Order order
    102 )
    103 {
    104   return _CPU_atomic_Load_ulong( object, order );
    105 }
     75#define _Atomic_Load_ulong( obj, order ) \
     76  _CPU_atomic_Load_ulong( obj, order )
    10677
    107 static inline void *_Atomic_Load_ptr(
    108   volatile Atomic_Pointer *object,
    109   Atomic_Order order
    110 )
    111 {
    112   return _CPU_atomic_Load_ptr( object, order );
    113 }
     78#define _Atomic_Load_ptr( obj, order ) \
     79  _CPU_atomic_Load_ptr( obj, order )
    11480
    115 /**
    116  * @brief Atomically store an atomic type value into a atomic object.
    117  *
    118  * @param object an atomic type pointer of object.
    119  * @param value a value to be stored into object.
    120  * @param order a type of Atomic_Order.
    121  *
    122  * The order shall not be ATOMIC_ORDER_ACQUIRE.
    123  */
    124 static inline void _Atomic_Store_uint(
    125   volatile Atomic_Uint *object,
    126   unsigned int value,
    127   Atomic_Order order
    128 )
    129 {
    130   _CPU_atomic_Store_uint( object, value, order );
    131 }
     81#define _Atomic_Store_uint( obj, desr, order ) \
     82  _CPU_atomic_Store_uint( obj, desr, order )
    13283
    133 static inline void _Atomic_Store_ulong(
    134   volatile Atomic_Ulong *object,
    135   unsigned long value,
    136   Atomic_Order order
    137 )
    138 {
    139   _CPU_atomic_Store_ulong( object, value, order );
    140 }
     84#define _Atomic_Store_ulong( obj, desr, order ) \
     85  _CPU_atomic_Store_ulong( obj, desr, order )
    14186
    142 static inline void _Atomic_Store_ptr(
    143   volatile Atomic_Pointer *object,
    144   void *pointer,
    145   Atomic_Order order
    146 )
    147 {
    148   _CPU_atomic_Store_ptr( object, pointer, order );
    149 }
     87#define _Atomic_Store_ptr( obj, desr, order ) \
     88  _CPU_atomic_Store_ptr( obj, desr, order )
    15089
    151 /**
    152  * @brief Atomically load-add-store an atomic type value into object
    153  *
    154  * @param object a atomic type pointer of object.
    155  * @param value a value to be add and store into object.
    156  * @param order a type of Atomic_Order.
    157  *
    158  * @retval a result value before add ops.
    159  */
    160 static inline unsigned int _Atomic_Fetch_add_uint(
    161   volatile Atomic_Uint *object,
    162   unsigned int value,
    163   Atomic_Order order
    164 )
    165 {
    166   return _CPU_atomic_Fetch_add_uint( object, value, order );
    167 }
     90#define _Atomic_Fetch_add_uint( obj, arg, order ) \
     91  _CPU_atomic_Fetch_add_uint( obj, arg, order )
    16892
    169 static inline unsigned long _Atomic_Fetch_add_ulong(
    170   volatile Atomic_Ulong *object,
    171   unsigned long value,
    172   Atomic_Order order
    173 )
    174 {
    175   return _CPU_atomic_Fetch_add_ulong( object, value, order );
    176 }
     93#define _Atomic_Fetch_add_ulong( obj, arg, order ) \
     94  _CPU_atomic_Fetch_add_ulong( obj, arg, order )
    17795
    178 static inline uintptr_t _Atomic_Fetch_add_ptr(
    179   volatile Atomic_Pointer *object,
    180   uintptr_t value,
    181   Atomic_Order order
    182 )
    183 {
    184   return _CPU_atomic_Fetch_add_ptr( object, value, order );
    185 }
     96#define _Atomic_Fetch_add_ptr( obj, arg, order ) \
     97  _CPU_atomic_Fetch_add_ptr( obj, arg, order )
    18698
    187 /**
    188  * @brief Atomically load-sub-store an atomic type value into object
    189  *
    190  * @param object a atomic type pointer of object.
    191  * @param value a value to be sub and store into object.
    192  * @param order a type of Atomic_Order.
    193  *
    194  * @retval a result value before sub ops.
    195  */
    196 static inline unsigned int _Atomic_Fetch_sub_uint(
    197   volatile Atomic_Uint *object,
    198   unsigned int value,
    199   Atomic_Order order
    200 )
    201 {
    202   return _CPU_atomic_Fetch_sub_uint( object, value, order );
    203 }
     99#define _Atomic_Fetch_sub_uint( obj, arg, order ) \
     100  _CPU_atomic_Fetch_sub_uint( obj, arg, order )
    204101
    205 static inline unsigned long _Atomic_Fetch_sub_ulong(
    206   volatile Atomic_Ulong *object,
    207   unsigned long value,
    208   Atomic_Order order
    209 )
    210 {
    211   return _CPU_atomic_Fetch_sub_ulong( object, value, order );
    212 }
     102#define _Atomic_Fetch_sub_ulong( obj, arg, order ) \
     103  _CPU_atomic_Fetch_sub_ulong( obj, arg, order )
    213104
    214 static inline uintptr_t _Atomic_Fetch_sub_ptr(
    215   volatile Atomic_Pointer *object,
    216   uintptr_t value,
    217   Atomic_Order order
    218 )
    219 {
    220   return _CPU_atomic_Fetch_sub_ptr( object, value, order );
    221 }
     105#define _Atomic_Fetch_sub_ptr( obj, arg, order ) \
     106  _CPU_atomic_Fetch_sub_ptr( obj, arg, order )
    222107
    223 /**
    224  * @brief Atomically load-or-store an atomic type value into object
    225  *
    226  * @param object a atomic type pointer of object.
    227  * @param value a value to be or and store into object.
    228  * @param order a type of Atomic_Order.
    229  *
    230  * @retval a result value before or ops.
    231  */
    232 static inline unsigned int _Atomic_Fetch_or_uint(
    233   volatile Atomic_Uint *object,
    234   unsigned int value,
    235   Atomic_Order order
    236 )
    237 {
    238   return _CPU_atomic_Fetch_or_uint( object, value, order );
    239 }
     108#define _Atomic_Fetch_or_uint( obj, arg, order ) \
     109  _CPU_atomic_Fetch_or_uint( obj, arg, order )
    240110
    241 static inline unsigned long _Atomic_Fetch_or_ulong(
    242   volatile Atomic_Ulong *object,
    243   unsigned long value,
    244   Atomic_Order order
    245 )
    246 {
    247   return _CPU_atomic_Fetch_or_ulong( object, value, order );
    248 }
     111#define _Atomic_Fetch_or_ulong( obj, arg, order ) \
     112  _CPU_atomic_Fetch_or_ulong( obj, arg, order )
    249113
    250 static inline uintptr_t _Atomic_Fetch_or_ptr(
    251   volatile Atomic_Pointer *object,
    252   uintptr_t value,
    253   Atomic_Order order
    254 )
    255 {
    256   return _CPU_atomic_Fetch_or_ptr( object, value, order );
    257 }
     114#define _Atomic_Fetch_or_ptr( obj, arg, order ) \
     115  _CPU_atomic_Fetch_or_ptr( obj, arg, order )
    258116
    259 /**
    260  * @brief Atomically load-and-store an atomic type value into object
    261  *
    262  * @param object a atomic type pointer of object.
    263  * @param value a value to be and and store into object.
    264  * @param order a type of Atomic_Order.
    265  *
    266  * @retval a result value before and ops.
    267  */
    268 static inline unsigned int _Atomic_Fetch_and_uint(
    269   volatile Atomic_Uint *object,
    270   unsigned int value,
    271   Atomic_Order order
    272 )
    273 {
    274   return _CPU_atomic_Fetch_and_uint( object, value, order );
    275 }
     117#define _Atomic_Fetch_and_uint( obj, arg, order ) \
     118  _CPU_atomic_Fetch_and_uint( obj, arg, order )
    276119
    277 static inline unsigned long _Atomic_Fetch_and_ulong(
    278   volatile Atomic_Ulong *object,
    279   unsigned long value,
    280   Atomic_Order order
    281 )
    282 {
    283   return _CPU_atomic_Fetch_and_ulong( object, value, order );
    284 }
     120#define _Atomic_Fetch_and_ulong( obj, arg, order ) \
     121  _CPU_atomic_Fetch_and_ulong( obj, arg, order )
    285122
    286 static inline uintptr_t _Atomic_Fetch_and_ptr(
    287   volatile Atomic_Pointer *object,
    288   uintptr_t value,
    289   Atomic_Order order
    290 )
    291 {
    292   return _CPU_atomic_Fetch_and_ptr( object, value, order );
    293 }
     123#define _Atomic_Fetch_and_ptr( obj, arg, order ) \
     124  _CPU_atomic_Fetch_and_ptr( obj, arg, order )
    294125
    295 /**
    296  * @brief Atomically exchange an atomic type value into object
    297  *
    298  * @param object a atomic type pointer of object.
    299  * @param value a value to exchange and and store into object.
    300  * @param order a type of Atomic_Order.
    301  *
    302  * @retval a result value before exchange ops.
    303  */
    304 static inline unsigned int _Atomic_Exchange_uint(
    305  volatile Atomic_Uint *object,
    306  unsigned int value,
    307  Atomic_Order order
    308 )
    309 {
    310   return _CPU_atomic_Exchange_uint( object, value, order );
    311 }
     126#define _Atomic_Exchange_uint( obj, desr, order ) \
     127  _CPU_atomic_Exchange_uint( obj, desr, order )
    312128
    313 static inline unsigned long _Atomic_Exchange_ulong(
    314  volatile Atomic_Ulong *object,
    315  unsigned long value,
    316  Atomic_Order order
    317 )
    318 {
    319   return _CPU_atomic_Exchange_ulong( object, value, order );
    320 }
     129#define _Atomic_Exchange_ulong( obj, desr, order ) \
     130  _CPU_atomic_Exchange_ulong( obj, desr, order )
    321131
    322 static inline void *_Atomic_Exchange_ptr(
    323  volatile Atomic_Pointer *object,
    324  void *pointer,
    325  Atomic_Order order
    326 )
    327 {
    328   return _CPU_atomic_Exchange_ptr( object, pointer, order );
    329 }
     132#define _Atomic_Exchange_ptr( obj, desr, order ) \
     133  _CPU_atomic_Exchange_ptr( obj, desr, order )
    330134
    331 /**
    332  * @brief Atomically compare the value stored at object with a
    333  * old_value and if the two values are equal, update the value of a
    334  * address with a new_value
    335  *
    336  * @param object a atomic type pointer of object.
    337  * @param old_value pointer of a value.
    338  * @param new_value a atomic type value.
    339  * @param order_succ a type of Atomic_Order for successful exchange.
    340  * @param order_fail a type of Atomic_Order for failed exchange.
    341  *
    342  * @retval true if the compare exchange successully.
    343  * @retval false if the compare exchange failed.
    344  */
    345 static inline bool _Atomic_Compare_exchange_uint(
    346   volatile Atomic_Uint *object,
    347   unsigned int *old_value,
    348   unsigned int new_value,
    349   Atomic_Order order_succ,
    350   Atomic_Order order_fail
    351 )
    352 {
    353   return _CPU_atomic_Compare_exchange_uint( object, old_value, new_value,
    354     order_succ, order_fail );
    355 }
     135#define _Atomic_Compare_exchange_uint( obj, expected, desired, succ, fail ) \
     136  _CPU_atomic_Compare_exchange_uint( obj, expected, desired, succ, fail )
    356137
    357 static inline bool _Atomic_Compare_exchange_ulong(
    358   volatile Atomic_Ulong *object,
    359   unsigned long *old_value,
    360   unsigned long new_value,
    361   Atomic_Order order_succ,
    362   Atomic_Order order_fail
    363 )
    364 {
    365   return _CPU_atomic_Compare_exchange_ulong( object, old_value, new_value,
    366     order_succ, order_fail );
    367 }
     138#define _Atomic_Compare_exchange_ulong( obj, expected, desired, succ, fail ) \
     139  _CPU_atomic_Compare_exchange_ulong( obj, expected, desired, succ, fail )
    368140
    369 static inline bool _Atomic_Compare_exchange_ptr(
    370   volatile Atomic_Pointer *object,
    371   void **old_pointer,
    372   void *new_pointer,
    373   Atomic_Order order_succ,
    374   Atomic_Order order_fail
    375 )
    376 {
    377   return _CPU_atomic_Compare_exchange_ptr( object, old_pointer, new_pointer,
    378     order_succ, order_fail );
    379 }
     141#define _Atomic_Compare_exchange_ptr( obj, expected, desired, succ, fail ) \
     142  _CPU_atomic_Compare_exchange_ptr( obj, expected, desired, succ, fail )
    380143
    381 /**
    382  * @brief Atomically clears an atomic flag.
    383  *
    384  * @param[in, out] object Pointer to the atomic flag object.
    385  * @param[in] order The atomic memory order.
    386  *
    387  */
    388 static inline void _Atomic_Flag_clear(
    389   volatile Atomic_Flag *object,
    390   Atomic_Order order
    391 )
    392 {
    393   _CPU_atomic_Flag_clear( object, order );
    394 }
     144#define _Atomic_Flag_clear( obj, order ) \
     145  _CPU_atomic_Flag_clear( obj, order )
    395146
    396 /**
    397  * @brief Atomically tests and sets an atomic flag.
    398  *
    399  * @param[in, out] object Pointer to the atomic flag object.
    400  * @param[in] order The atomic memory order.
    401  *
    402  * @retval true The atomic flag was already set.
    403  * @retval false Otherwise.
    404  */
    405 static inline bool _Atomic_Flag_test_and_set(
    406   volatile Atomic_Flag *object,
    407   Atomic_Order order
    408 )
    409 {
    410   return _CPU_atomic_Flag_test_and_set( object, order );
    411 }
     147#define _Atomic_Flag_test_and_set( obj, order ) \
     148  _CPU_atomic_Flag_test_and_set( obj, order )
    412149
    413 #ifdef __cplusplus
    414 }
    415 #endif
     150/** @} */
    416151
    417 /**@}*/
    418 #endif
    419 /*  end of include file */
     152#endif /* _RTEMS_SCORE_ATOMIC_H */
  • cpukit/score/include/rtems/score/cpustdatomic.h

    rb42e148 r89f8eab5  
    11/**
    2  * @file  rtems/score/cpustdatomic.h
     2 * @file
    33 *
    4  * This include file defines the generic data struct and implementation
    5  * based on stdatomic.h for all the support architectures. You should not
    6  * include this header file directly, because it will be used by atomic.h
    7  * which should be included by score components
     4 * @brief Atomic Operations CPU API
    85 */
    96
     
    1613 */
    1714
    18 #ifndef _RTEMS_SCORE_GENERAL_STDATOMIC_CPU_H_
    19 #define _RTEMS_SCORE_GENERAL_STDATOMIC_CPU_H_
     15#ifndef _RTEMS_SCORE_CPUSTDATOMIC_H
     16#define _RTEMS_SCORE_CPUSTDATOMIC_H
     17
     18#include <stdint.h>
     19
     20#if defined(__cplusplus) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 9
     21
     22/*
     23 * The GCC 4.9 ships its own <stdatomic.h> which is not C++ compatible.  The
     24 * suggested solution was to include <atomic> in case C++ is used.  This works
     25 * at least with GCC 4.9.  See also:
     26 *
     27 * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60932
     28 * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60940
     29 */
     30
     31#include <atomic>
     32
     33typedef std::atomic_uint CPU_atomic_Uint;
     34
     35typedef std::atomic_ulong CPU_atomic_Ulong;
     36
     37typedef std::atomic_uintptr_t CPU_atomic_Pointer;
     38
     39typedef std::atomic_flag CPU_atomic_Flag;
     40
     41#define CPU_ATOMIC_ORDER_RELAXED std::memory_order_relaxed
     42
     43#define CPU_ATOMIC_ORDER_ACQUIRE std::memory_order_acquire
     44
     45#define CPU_ATOMIC_ORDER_RELEASE std::memory_order_release
     46
     47#define CPU_ATOMIC_ORDER_SEQ_CST std::memory_order_seq_cst
     48
     49#define CPU_ATOMIC_INITIALIZER_UINT( value ) ATOMIC_VAR_INIT( value )
     50
     51#define CPU_ATOMIC_INITIALIZER_ULONG( value ) ATOMIC_VAR_INIT( value )
     52
     53#define CPU_ATOMIC_INITIALIZER_PTR( value ) \
     54  ATOMIC_VAR_INIT( (uintptr_t) (value) )
     55
     56#define CPU_ATOMIC_INITIALIZER_FLAG ATOMIC_FLAG_INIT
     57
     58#define _CPU_atomic_Fence( order ) atomic_thread_fence( order )
     59
     60#define _CPU_atomic_Init_uint( obj, desired ) \
     61  (obj)->store( desired )
     62
     63#define _CPU_atomic_Init_ulong( obj, desired ) \
     64  (obj)->store( desired )
     65
     66#define _CPU_atomic_Init_ptr( obj, desired ) \
     67  (obj)->store( desired )
     68
     69#define _CPU_atomic_Load_uint( obj, order ) \
     70  (obj)->load( order )
     71
     72#define _CPU_atomic_Load_ulong( obj, order ) \
     73  (obj)->load( order )
     74
     75#define _CPU_atomic_Load_ptr( obj, order ) \
     76  (void *) (obj)->load( order )
     77
     78#define _CPU_atomic_Store_uint( obj, desr, order ) \
     79  (obj)->store( desr, order )
     80
     81#define _CPU_atomic_Store_ulong( obj, desr, order ) \
     82  (obj)->store( desr, order )
     83
     84#define _CPU_atomic_Store_ptr( obj, desr, order ) \
     85  (obj)->store( (uintptr_t) desr, order )
     86
     87#define _CPU_atomic_Fetch_add_uint( obj, arg, order ) \
     88  (obj)->fetch_add( arg, order )
     89
     90#define _CPU_atomic_Fetch_add_ulong( obj, arg, order ) \
     91  (obj)->fetch_add( arg, order )
     92
     93#define _CPU_atomic_Fetch_add_ptr( obj, arg, order ) \
     94  (obj)->fetch_add( arg, (uintptr_t) order )
     95
     96#define _CPU_atomic_Fetch_sub_uint( obj, arg, order ) \
     97  (obj)->fetch_sub( arg, order )
     98
     99#define _CPU_atomic_Fetch_sub_ulong( obj, arg, order ) \
     100  (obj)->fetch_sub( arg, order )
     101
     102#define _CPU_atomic_Fetch_sub_ptr( obj, arg, order ) \
     103  (obj)->fetch_sub( arg, (uintptr_t) order )
     104
     105#define _CPU_atomic_Fetch_or_uint( obj, arg, order ) \
     106  (obj)->fetch_or( arg, order )
     107
     108#define _CPU_atomic_Fetch_or_ulong( obj, arg, order ) \
     109  (obj)->fetch_or( arg, order )
     110
     111#define _CPU_atomic_Fetch_or_ptr( obj, arg, order ) \
     112  (obj)->fetch_or( arg, (uintptr_t) order )
     113
     114#define _CPU_atomic_Fetch_and_uint( obj, arg, order ) \
     115  (obj)->fetch_and( arg, order )
     116
     117#define _CPU_atomic_Fetch_and_ulong( obj, arg, order ) \
     118  (obj)->fetch_and( arg, order )
     119
     120#define _CPU_atomic_Fetch_and_ptr( obj, arg, order ) \
     121  (obj)->fetch_and( arg, (uintptr_t) order )
     122
     123#define _CPU_atomic_Exchange_uint( obj, desr, order ) \
     124  (obj)->exchange( desr, order )
     125
     126#define _CPU_atomic_Exchange_ulong( obj, desr, order ) \
     127  (obj)->exchange( desr, order )
     128
     129#define _CPU_atomic_Exchange_ptr( obj, desr, order ) \
     130  (void *) (obj)->exchange( desr, (uintptr_t) order )
     131
     132#define _CPU_atomic_Compare_exchange_uint( obj, expected, desired, succ, fail ) \
     133  (obj)->compare_exchange_strong( expected, desired, succ, fail )
     134
     135#define _CPU_atomic_Compare_exchange_ulong( obj, expected, desired, succ, fail ) \
     136  (obj)->compare_exchange_strong( expected, desired, succ, fail )
     137
     138#define _CPU_atomic_Compare_exchange_ptr( obj, expected, desired, succ, fail ) \
     139  (obj)->compare_exchange_strong( (void **) expected, (uintptr_t) desired, succ, fail )
     140
     141#define _CPU_atomic_Flag_clear( obj, order ) \
     142  (obj)->clear( order )
     143
     144#define _CPU_atomic_Flag_test_and_set( obj, order ) \
     145  (obj)->test_and_set( order )
     146
     147#else /* __cplusplus */
    20148
    21149#include <stdatomic.h>
    22 #include <stdbool.h>
    23 #include <stdint.h>
    24 
    25 #ifdef __cplusplus
    26 extern "C" {
    27 #endif
    28 
    29 /**
    30  * @defgroup RTEMS general stdatomic data type and implementation.
    31  *
    32  */
    33 
    34 /**@{*/
    35 
    36 /**
    37  * @brief atomic operation unsigned integer type
    38  */
    39 typedef atomic_uint Atomic_Uint;
    40 
    41 /**
    42  * @brief atomic operation unsigned long integer type
    43  */
    44 typedef atomic_ulong Atomic_Ulong;
    45 
    46 /**
    47  * @brief atomic operation unsigned integer the size of a pointer type
    48  */
    49 typedef atomic_uintptr_t Atomic_Pointer;
    50 
    51 /**
    52  * @brief atomic operation flag type
    53  */
    54 typedef atomic_flag Atomic_Flag;
    55 
    56 /**
    57  * @brief Memory order according to ISO/IEC 9899:2011.
    58  */
    59 typedef enum {
    60   ATOMIC_ORDER_RELAXED = memory_order_relaxed,
    61   ATOMIC_ORDER_ACQUIRE = memory_order_acquire,
    62   ATOMIC_ORDER_RELEASE = memory_order_release,
    63   ATOMIC_ORDER_SEQ_CST = memory_order_seq_cst
    64 } Atomic_Order;
    65 
    66 
    67 /**
    68  * @brief atomic data initializer for static initialization.
    69  */
    70 #define CPU_ATOMIC_INITIALIZER_UINT(value) ATOMIC_VAR_INIT(value)
    71 #define CPU_ATOMIC_INITIALIZER_ULONG(value) ATOMIC_VAR_INIT(value)
    72 #define CPU_ATOMIC_INITIALIZER_PTR(pointer) \
    73   ATOMIC_VAR_INIT((uintptr_t) pointer)
     150
     151typedef atomic_uint CPU_atomic_Uint;
     152
     153typedef atomic_ulong CPU_atomic_Ulong;
     154
     155typedef atomic_uintptr_t CPU_atomic_Pointer;
     156
     157typedef atomic_flag CPU_atomic_Flag;
     158
     159#define CPU_ATOMIC_ORDER_RELAXED memory_order_relaxed
     160
     161#define CPU_ATOMIC_ORDER_ACQUIRE memory_order_acquire
     162
     163#define CPU_ATOMIC_ORDER_RELEASE memory_order_release
     164
     165#define CPU_ATOMIC_ORDER_SEQ_CST memory_order_seq_cst
     166
     167#define CPU_ATOMIC_INITIALIZER_UINT( value ) ATOMIC_VAR_INIT( value )
     168
     169#define CPU_ATOMIC_INITIALIZER_ULONG( value ) ATOMIC_VAR_INIT( value )
     170
     171#define CPU_ATOMIC_INITIALIZER_PTR( value ) \
     172  ATOMIC_VAR_INIT( (uintptr_t) (value) )
    74173
    75174#define CPU_ATOMIC_INITIALIZER_FLAG ATOMIC_FLAG_INIT
    76175
    77 static inline void _CPU_atomic_Fence(
    78   Atomic_Order order
    79 )
    80 {
    81   atomic_thread_fence( (memory_order) order );
    82 }
    83 
    84 /**
    85  * @brief Initializes an atomic type value into a atomic object.
    86  *
    87  * @param object an atomic type pointer of object.
    88  * @param value a value to be stored into object.
    89  */
    90 static inline void _CPU_atomic_Init_uint(
    91   volatile Atomic_Uint *object,
    92   unsigned int value
    93 )
    94 {
    95   atomic_init( object, value );
    96 }
    97 
    98 static inline void _CPU_atomic_Init_ulong(
    99   volatile Atomic_Ulong *object,
    100   unsigned long value
    101 )
    102 {
    103   atomic_init( object, value );
    104 }
    105 
    106 static inline void _CPU_atomic_Init_ptr(
    107   volatile Atomic_Pointer *object,
    108   void *pointer
    109 )
    110 {
    111   atomic_init( object, (uintptr_t) pointer );
    112 }
    113 
    114 /**
    115  * @brief Atomically load an atomic type value from atomic object.
    116  *
    117  * @param object an atomic type pointer of object.
    118  * @param order a type of Atomic_Order.
    119  *
    120  * The order shall not be ATOMIC_ORDER_RELEASE.
    121  */
    122 static inline unsigned int _CPU_atomic_Load_uint(
    123   volatile Atomic_Uint *object,
    124   Atomic_Order order
    125 )
    126 {
    127   return atomic_load_explicit( object, (memory_order) order );
    128 }
    129 
    130 static inline unsigned long _CPU_atomic_Load_ulong(
    131   volatile Atomic_Ulong *object,
    132   Atomic_Order order
    133 )
    134 {
    135   return atomic_load_explicit( object, (memory_order) order );
    136 }
    137 
    138 static inline void *_CPU_atomic_Load_ptr(
    139   volatile Atomic_Pointer *object,
    140   Atomic_Order order
    141 )
    142 {
    143   return (void *) atomic_load_explicit( object, (memory_order) order );
    144 }
    145 
    146 /**
    147  * @brief Atomically store an atomic type value into a atomic object.
    148  *
    149  * @param object an atomic type pointer of object.
    150  * @param value a value to be stored into object.
    151  * @param order a type of Atomic_Order.
    152  *
    153  * The order shall not be ATOMIC_ORDER_ACQUIRE.
    154  */
    155 static inline void _CPU_atomic_Store_uint(
    156   volatile Atomic_Uint *object,
    157   unsigned int value,
    158   Atomic_Order order
    159 )
    160 {
    161   atomic_store_explicit( object, value, (memory_order) order );
    162 }
    163 
    164 static inline void _CPU_atomic_Store_ulong(
    165   volatile Atomic_Ulong *object,
    166   unsigned long value,
    167   Atomic_Order order
    168 )
    169 {
    170   atomic_store_explicit( object, value, (memory_order) order );
    171 }
    172 
    173 static inline void _CPU_atomic_Store_ptr(
    174   volatile Atomic_Pointer *object,
    175   void *pointer,
    176   Atomic_Order order
    177 )
    178 {
    179   atomic_store_explicit( object, pointer, (memory_order) order );
    180 }
    181 
    182 /**
    183  * @brief Atomically load-add-store an atomic type value into object
    184  *
    185  * @param object a atomic type pointer of object.
    186  * @param value a value to be add and store into object.
    187  * @param order a type of Atomic_Order.
    188  *
    189  * @retval a result value before add ops.
    190  */
    191 static inline unsigned int _CPU_atomic_Fetch_add_uint(
    192   volatile Atomic_Uint *object,
    193   unsigned int value,
    194   Atomic_Order order
    195 )
    196 {
    197   return atomic_fetch_add_explicit( object, value, (memory_order) order );
    198 }
    199 
    200 static inline unsigned long _CPU_atomic_Fetch_add_ulong(
    201   volatile Atomic_Ulong *object,
    202   unsigned long value,
    203   Atomic_Order order
    204 )
    205 {
    206   return atomic_fetch_add_explicit( object, value, (memory_order) order );
    207 }
    208 
    209 static inline uintptr_t _CPU_atomic_Fetch_add_ptr(
    210   volatile Atomic_Pointer *object,
    211   uintptr_t value,
    212   Atomic_Order order
    213 )
    214 {
    215   return atomic_fetch_add_explicit( object, value, (memory_order) order );
    216 }
    217 
    218 /**
    219  * @brief Atomically load-sub-store an atomic type value into object
    220  *
    221  * @param object a atomic type pointer of object.
    222  * @param value a value to be sub and store into object.
    223  * @param order a type of Atomic_Order.
    224  *
    225  * @retval a result value before sub ops.
    226  */
    227 static inline unsigned int _CPU_atomic_Fetch_sub_uint(
    228   volatile Atomic_Uint *object,
    229   unsigned int value,
    230   Atomic_Order order
    231 )
    232 {
    233   return atomic_fetch_sub_explicit( object, value, (memory_order) order );
    234 }
    235 
    236 static inline unsigned long _CPU_atomic_Fetch_sub_ulong(
    237   volatile Atomic_Ulong *object,
    238   unsigned long value,
    239   Atomic_Order order
    240 )
    241 {
    242   return atomic_fetch_sub_explicit( object, value, (memory_order) order );
    243 }
    244 
    245 static inline uintptr_t _CPU_atomic_Fetch_sub_ptr(
    246   volatile Atomic_Pointer *object,
    247   uintptr_t value,
    248   Atomic_Order order
    249 )
    250 {
    251   return atomic_fetch_sub_explicit( object, value, (memory_order) order );
    252 }
    253 
    254 /**
    255  * @brief Atomically load-or-store an atomic type value into object
    256  *
    257  * @param object a atomic type pointer of object.
    258  * @param value a value to be or and store into object.
    259  * @param order a type of Atomic_Order.
    260  *
    261  * @retval a result value before or ops.
    262  */
    263 static inline unsigned int _CPU_atomic_Fetch_or_uint(
    264   volatile Atomic_Uint *object,
    265   unsigned int value,
    266   Atomic_Order order
    267 )
    268 {
    269   return atomic_fetch_or_explicit( object, value, (memory_order) order );
    270 }
    271 
    272 static inline unsigned long _CPU_atomic_Fetch_or_ulong(
    273   volatile Atomic_Ulong *object,
    274   unsigned long value,
    275   Atomic_Order order
    276 )
    277 {
    278   return atomic_fetch_or_explicit( object, value, (memory_order) order );
    279 }
    280 
    281 static inline uintptr_t _CPU_atomic_Fetch_or_ptr(
    282   volatile Atomic_Pointer *object,
    283   uintptr_t value,
    284   Atomic_Order order
    285 )
    286 {
    287   return atomic_fetch_or_explicit( object, value, (memory_order) order );
    288 }
    289 
    290 /**
    291  * @brief Atomically load-and-store an atomic type value into object
    292  *
    293  * @param object a atomic type pointer of object.
    294  * @param value a value to be and and store into object.
    295  * @param order a type of Atomic_Order.
    296  *
    297  * @retval a result value before and ops.
    298  */
    299 static inline unsigned int _CPU_atomic_Fetch_and_uint(
    300   volatile Atomic_Uint *object,
    301   unsigned int value,
    302   Atomic_Order order
    303 )
    304 {
    305   return atomic_fetch_and_explicit( object, value, (memory_order) order );
    306 }
    307 
    308 static inline unsigned long _CPU_atomic_Fetch_and_ulong(
    309   volatile Atomic_Ulong *object,
    310   unsigned long value,
    311   Atomic_Order order
    312 )
    313 {
    314   return atomic_fetch_and_explicit( object, value, (memory_order) order );
    315 }
    316 
    317 static inline uintptr_t _CPU_atomic_Fetch_and_ptr(
    318   volatile Atomic_Pointer *object,
    319   uintptr_t value,
    320   Atomic_Order order
    321 )
    322 {
    323   return atomic_fetch_and_explicit( object, value, (memory_order) order );
    324 }
    325 
    326 /**
    327  * @brief Atomically exchange an atomic type value into object
    328  *
    329  * @param object a atomic type pointer of object.
    330  * @param value a value to exchange and and store into object.
    331  * @param order a type of Atomic_Order.
    332  *
    333  * @retval a result value before exchange ops.
    334  */
    335 static inline unsigned int _CPU_atomic_Exchange_uint(
    336  volatile Atomic_Uint *object,
    337  unsigned int value,
    338  Atomic_Order order
    339 )
    340 {
    341   return atomic_exchange_explicit( object, value, (memory_order) order );
    342 }
    343 
    344 static inline unsigned long _CPU_atomic_Exchange_ulong(
    345  volatile Atomic_Ulong *object,
    346  unsigned long value,
    347  Atomic_Order order
    348 )
    349 {
    350   return atomic_exchange_explicit( object, value, (memory_order) order );
    351 }
    352 
    353 static inline void *_CPU_atomic_Exchange_ptr(
    354  volatile Atomic_Pointer *object,
    355  void *pointer,
    356  Atomic_Order order
    357 )
    358 {
    359   return (void *) atomic_exchange_explicit(
    360     object,
    361     (uintptr_t) pointer,
    362     (memory_order) order
    363   );
    364 }
    365 
    366 /**
    367  * @brief Atomically compare the value stored at object with a
    368  * old_value and if the two values are equal, update the value of a
    369  * address with a new_value
    370  *
    371  * @param object a atomic type pointer of object.
    372  * @param old_value pointer of a value.
    373  * @param new_value a atomic type value.
    374  * @param order_succ a type of Atomic_Order for successful exchange.
    375  * @param order_fail a type of Atomic_Order for failed exchange.
    376  *
    377  * @retval true if the compare exchange successully.
    378  * @retval false if the compare exchange failed.
    379  */
    380 static inline bool _CPU_atomic_Compare_exchange_uint(
    381   volatile Atomic_Uint *object,
    382   unsigned int *old_value,
    383   unsigned int new_value,
    384   Atomic_Order order_succ,
    385   Atomic_Order order_fail
    386 )
    387 {
    388   return atomic_compare_exchange_strong_explicit( object, old_value,
    389     new_value, order_succ, order_fail );
    390 }
    391 
    392 static inline bool _CPU_atomic_Compare_exchange_ulong(
    393   volatile Atomic_Ulong *object,
    394   unsigned long *old_value,
    395   unsigned long new_value,
    396   Atomic_Order order_succ,
    397   Atomic_Order order_fail
    398 )
    399 {
    400   return atomic_compare_exchange_strong_explicit( object, old_value,
    401     new_value, order_succ, order_fail );
    402 }
    403 
    404 static inline bool _CPU_atomic_Compare_exchange_ptr(
    405   volatile Atomic_Pointer *object,
    406   void **old_pointer,
    407   void *new_pointer,
    408   Atomic_Order order_succ,
    409   Atomic_Order order_fail
    410 )
    411 {
    412   return atomic_compare_exchange_strong_explicit( object, old_pointer,
    413     new_pointer, order_succ, order_fail );
    414 }
    415 
    416 static inline void _CPU_atomic_Flag_clear(
    417   volatile Atomic_Flag *object,
    418   Atomic_Order order
    419 )
    420 {
    421   return atomic_flag_clear_explicit( object, (memory_order) order );
    422 }
    423 
    424 static inline bool _CPU_atomic_Flag_test_and_set(
    425   volatile Atomic_Flag *object,
    426   Atomic_Order order
    427 )
    428 {
    429   return atomic_flag_test_and_set_explicit( object, (memory_order) order );
    430 }
    431 
    432 #ifdef __cplusplus
    433 }
    434 #endif
    435 
    436 /**@}*/
    437 #endif
    438 /*  end of include file */
     176#define _CPU_atomic_Fence( order ) atomic_thread_fence( order )
     177
     178#define _CPU_atomic_Init_uint( obj, desired ) \
     179  atomic_init( obj, desired )
     180
     181#define _CPU_atomic_Init_ulong( obj, desired ) \
     182  atomic_init( obj, desired )
     183
     184#define _CPU_atomic_Init_ptr( obj, desired ) \
     185  atomic_init( obj, (uintptr_t) desired )
     186
     187#define _CPU_atomic_Load_uint( obj, order ) \
     188  atomic_load_explicit( obj, order )
     189
     190#define _CPU_atomic_Load_ulong( obj, order ) \
     191  atomic_load_explicit( obj, order )
     192
     193#define _CPU_atomic_Load_ptr( obj, order ) \
     194  (void *) atomic_load_explicit( obj, order )
     195
     196#define _CPU_atomic_Store_uint( obj, desr, order ) \
     197  atomic_store_explicit( obj, desr, order )
     198
     199#define _CPU_atomic_Store_ulong( obj, desr, order ) \
     200  atomic_store_explicit( obj, desr, order )
     201
     202#define _CPU_atomic_Store_ptr( obj, desr, order ) \
     203  atomic_store_explicit( obj, desr, order )
     204
     205#define _CPU_atomic_Fetch_add_uint( obj, arg, order ) \
     206  atomic_fetch_add_explicit( obj, arg, order )
     207
     208#define _CPU_atomic_Fetch_add_ulong( obj, arg, order ) \
     209  atomic_fetch_add_explicit( obj, arg, order )
     210
     211#define _CPU_atomic_Fetch_add_ptr( obj, arg, order ) \
     212  atomic_fetch_add_explicit( obj, arg, order )
     213
     214#define _CPU_atomic_Fetch_sub_uint( obj, arg, order ) \
     215  atomic_fetch_sub_explicit( obj, arg, order )
     216
     217#define _CPU_atomic_Fetch_sub_ulong( obj, arg, order ) \
     218  atomic_fetch_sub_explicit( obj, arg, order )
     219
     220#define _CPU_atomic_Fetch_sub_ptr( obj, arg, order ) \
     221  atomic_fetch_sub_explicit( obj, arg, order )
     222
     223#define _CPU_atomic_Fetch_or_uint( obj, arg, order ) \
     224  atomic_fetch_or_explicit( obj, arg, order )
     225
     226#define _CPU_atomic_Fetch_or_ulong( obj, arg, order ) \
     227  atomic_fetch_or_explicit( obj, arg, order )
     228
     229#define _CPU_atomic_Fetch_or_ptr( obj, arg, order ) \
     230  atomic_fetch_or_explicit( obj, arg, order )
     231
     232#define _CPU_atomic_Fetch_and_uint( obj, arg, order ) \
     233  atomic_fetch_and_explicit( obj, arg, order )
     234
     235#define _CPU_atomic_Fetch_and_ulong( obj, arg, order ) \
     236  atomic_fetch_and_explicit( obj, arg, order )
     237
     238#define _CPU_atomic_Fetch_and_ptr( obj, arg, order ) \
     239  atomic_fetch_and_explicit( obj, arg, order )
     240
     241#define _CPU_atomic_Exchange_uint( obj, desr, order ) \
     242  atomic_exchange_explicit( obj, desr, order )
     243
     244#define _CPU_atomic_Exchange_ulong( obj, desr, order ) \
     245  atomic_exchange_explicit( obj, desr, order )
     246
     247#define _CPU_atomic_Exchange_ptr( obj, desr, order ) \
     248  atomic_exchange_explicit( obj, desr, order )
     249
     250#define _CPU_atomic_Compare_exchange_uint( obj, expected, desired, succ, fail ) \
     251  atomic_compare_exchange_strong_explicit( obj, expected, desired, succ, fail )
     252
     253#define _CPU_atomic_Compare_exchange_ulong( obj, expected, desired, succ, fail ) \
     254  atomic_compare_exchange_strong_explicit( obj, expected, desired, succ, fail )
     255
     256#define _CPU_atomic_Compare_exchange_ptr( obj, expected, desired, succ, fail ) \
     257  atomic_compare_exchange_strong_explicit( obj, expected, desired, succ, fail )
     258
     259#define _CPU_atomic_Flag_clear( obj, order ) \
     260  atomic_flag_clear_explicit( obj, order )
     261
     262#define _CPU_atomic_Flag_test_and_set( obj, order ) \
     263  atomic_flag_test_and_set_explicit( obj, order )
     264
     265#endif /* __cplusplus */
     266
     267#endif /* _RTEMS_SCORE_CPUSTDATOMIC_H */
Note: See TracChangeset for help on using the changeset viewer.