summaryrefslogblamecommitdiffstats
path: root/cpukit/score/include/rtems/score/cpustdatomic.h
blob: 222ad78852f338d225e2b196bbd428fdddea9d43 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14













                                                                         
                                        





                                             
                    
                   














                                                                  




                                                     
                                  






























                                                                              



                                                            
                                                                 
                                                                  

                                             

                                                    
 






                                              





                                                                







                                         


                                          

 
                               

 
                                        
                                  
               

 
                                             

 







                                                                  







                                                              

                                                   


                    
                                                              

 
                                         



                                  
                                                                       










                                                                     








                                                               


                                           


                    
                                                               

 
                                         
                                  
                


                    
                                                                 








                                                                    
                                         
   








                                                                          


                                                        


                    
                                                                          

 
                                                  




                                  
                                                                          








                                                                    
                                         
   








                                                                          


                                                        


                    
                                                                          

 
                                                  




                                  
                                                                          








                                                                   
                                        
   








                                                                         


                                                       


                    
                                                                         

 
                                                 




                                  
                                                                         








                                                                    
                                         
   








                                                                          


                                                        


                    
                                                                          

 
                                                  




                                  
                                                                          








                                                              
                                              
   








                                                                         


                                                       


                   
                                                                         

 
                                             
                                 
               


                   




                                           















                                                                     











                                                                    



                                                      







                                                                    
                                                    
                                  

                     



                          

                                                                      

 


                                          

 
                                                                    

 


                                                 

 
                                                                           








                          
/**
 * @file  rtems/score/cpustdatomic.h
 * 
 * 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
 */

/*
 * COPYRIGHT (c) 2013 Deng Hengyi.
 *
 * The license and distribution terms for this file may be
 * found in the file LICENSE in this distribution or at
 * http://www.rtems.org/license/LICENSE.
 */

#ifndef _RTEMS_SCORE_GENERAL_STDATOMIC_CPU_H_
#define _RTEMS_SCORE_GENERAL_STDATOMIC_CPU_H_

#include <stdatomic.h>
#include <stdbool.h>
#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @defgroup RTEMS general stdatomic data type and implementation.
 *
 */

/**@{*/

/**
 * @brief atomic operation unsigned integer type
 */
typedef atomic_uint Atomic_Uint;

/**
 * @brief atomic operation unsigned long integer type
 */
typedef atomic_ulong Atomic_Ulong;

/**
 * @brief atomic operation unsigned integer the size of a pointer type
 */
typedef atomic_uintptr_t Atomic_Pointer;

/**
 * @brief atomic operation flag type
 */
typedef atomic_flag Atomic_Flag;

/**
 * @brief the enumeration Atomic_Memory_barrier specifies the detailed regular
 * memory synchronization operations used in the atomic operation API
 * definitions.
 */
typedef enum {
  /** no operation orders memory. */
  ATOMIC_ORDER_RELAXED = memory_order_relaxed,
  /** a load operation performs an acquire operation on the affected memory
  * location. This flag guarantees that the effects of load operation are
  * completed before the effects of any later data accesses.
  */
  ATOMIC_ORDER_ACQUIRE = memory_order_acquire,
  /** a store operation performs a release operation on the affected memory
  * location. This flag guarantee that all effects of all previous data
  * accesses are completed before the store operation takes place.
  */
  ATOMIC_ORDER_RELEASE = memory_order_release
} Atomic_Order;


/**
 * @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_INITIALIZER_FLAG ATOMIC_FLAG_INIT

static inline void _CPU_atomic_Fence(
  Atomic_Order order
)
{
  atomic_thread_fence( (memory_order) 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 );
}

/**
 * @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 );
}

/**
 * @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 );
}

/**
 * @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 );
}

/**
 * @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 );
}

/**
 * @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 );
}

/**
 * @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 );
}

/**
 * @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
  );
}

/**
 * @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 */