/** * @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. */ /* * COPYRIGHT (c) 2012 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.com/license/LICENSE. */ #ifndef _RTEMS_SCORE_ATOMIC_H #define _RTEMS_SCORE_ATOMIC_H #include #ifdef __cplusplus extern "C" { #endif /** * @defgroup RTEMS atomic interface * */ /**@{*/ /** * @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_RELAXED_BARRIER, /** 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_ACQUIRE_BARRIER, /** 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_RELEASE_BARRIER } Atomic_Memory_barrier; /** * @brief Atomically load an atomic type value from address @a address with * a type of Atomic_Memory_barrier @a memory_barrier. The @a memory_barrier * shall not be ATOMIC_RELEASE_BARRIER. */ RTEMS_INLINE_ROUTINE Atomic_Int _Atomic_Load_int( volatile Atomic_Int *address, Atomic_Memory_barrier memory_barrier ); RTEMS_INLINE_ROUTINE Atomic_Long _Atomic_Load_long( volatile Atomic_Long *address, Atomic_Memory_barrier memory_barrier ); RTEMS_INLINE_ROUTINE Atomic_Pointer _Atomic_Load_ptr( volatile Atomic_Pointer *address, Atomic_Memory_barrier memory_barrier ); RTEMS_INLINE_ROUTINE Atomic_Int32 _Atomic_Load_32( volatile Atomic_Int32 *address, Atomic_Memory_barrier memory_barrier ); RTEMS_INLINE_ROUTINE Atomic_Int64 _Atomic_Load_64( volatile Atomic_Int64 *address, Atomic_Memory_barrier memory_barrier ); /** * @brief Atomically store an atomic type value @a value into address @a * address with a type of Atomic_Memory_barrier @a memory_barrier. The @a * memory_barrier shall not be ATOMIC_ACQUIRE_BARRIER. */ RTEMS_INLINE_ROUTINE void _Atomic_Store_int( volatile Atomic_Int *address, Atomic_Int value, Atomic_Memory_barrier memory_barrier ); RTEMS_INLINE_ROUTINE void _Atomic_Store_long( volatile Atomic_Long *address, Atomic_Long value, Atomic_Memory_barrier memory_barrier ); RTEMS_INLINE_ROUTINE void _Atomic_Store_ptr( volatile Atomic_Pointer *address, Atomic_Pointer value, Atomic_Memory_barrier memory_barrier ); RTEMS_INLINE_ROUTINE void _Atomic_Store_32( volatile Atomic_Int32 *address, Atomic_Int32 value, Atomic_Memory_barrier memory_barrier ); RTEMS_INLINE_ROUTINE void _Atomic_Store_64( volatile Atomic_Int64 *address, Atomic_Int64 value, Atomic_Memory_barrier memory_barrier ); /** * @brief Atomically load-add-store an atomic type value @a value into address * @a address with a type of Atomic_Memory_barrier @a memory_barrier. */ RTEMS_INLINE_ROUTINE void _Atomic_Fetch_add_int( volatile Atomic_Int *address, Atomic_Int value, Atomic_Memory_barrier memory_barrier ); RTEMS_INLINE_ROUTINE void _Atomic_Fetch_add_long( volatile Atomic_Long *address, Atomic_Long value, Atomic_Memory_barrier memory_barrier ); RTEMS_INLINE_ROUTINE void _Atomic_Fetch_add_ptr( volatile Atomic_Pointer *address, Atomic_Pointer value, Atomic_Memory_barrier memory_barrier ); RTEMS_INLINE_ROUTINE void _Atomic_Fetch_add_32( volatile Atomic_Int32 *address, Atomic_Int32 value, Atomic_Memory_barrier memory_barrier ); RTEMS_INLINE_ROUTINE void _Atomic_Fetch_add_64( volatile Atomic_Int64 *address, Atomic_Int64 value, Atomic_Memory_barrier memory_barrier ); /** * @brief Atomically load-sub-store an atomic type value @a value into address * @a address with a type of Atomic_Memory_barrier @a memory_barrier. */ RTEMS_INLINE_ROUTINE void _Atomic_Fetch_sub_int( volatile Atomic_Int *address, Atomic_Int value, Atomic_Memory_barrier memory_barrier ); RTEMS_INLINE_ROUTINE void _Atomic_Fetch_sub_long( volatile Atomic_Long *address, Atomic_Long value, Atomic_Memory_barrier memory_barrier ); RTEMS_INLINE_ROUTINE void _Atomic_Fetch_sub_ptr( volatile Atomic_Pointer *address, Atomic_Pointer value, Atomic_Memory_barrier memory_barrier ); RTEMS_INLINE_ROUTINE void _Atomic_Fetch_sub_32( volatile Atomic_Int32 *address, Atomic_Int32 value, Atomic_Memory_barrier memory_barrier ); RTEMS_INLINE_ROUTINE void _Atomic_Fetch_sub_64( volatile Atomic_Int64 *address, Atomic_Int64 value, Atomic_Memory_barrier memory_barrier ); /** * @brief Atomically load-or-store an atomic type value @a value into address * @a address with a type of Atomic_Memory_barrier @a memory_barrier. */ RTEMS_INLINE_ROUTINE void _Atomic_Fetch_or_int( volatile Atomic_Int *address, Atomic_Int value, Atomic_Memory_barrier memory_barrier ); RTEMS_INLINE_ROUTINE void _Atomic_Fetch_or_long( volatile Atomic_Long *address, Atomic_Long value, Atomic_Memory_barrier memory_barrier ); RTEMS_INLINE_ROUTINE void _Atomic_Fetch_or_ptr( volatile Atomic_Pointer *address, Atomic_Pointer value, Atomic_Memory_barrier memory_barrier ); RTEMS_INLINE_ROUTINE void _Atomic_Fetch_or_32( volatile Atomic_Int32 *address, Atomic_Int32 value, Atomic_Memory_barrier memory_barrier ); RTEMS_INLINE_ROUTINE void _Atomic_Fetch_or_64( volatile Atomic_Int64 *address, Atomic_Int64 value, Atomic_Memory_barrier memory_barrier ); /** * @brief Atomically load-and-store an atomic type value @a value into address * @a address with a type of Atomic_Memory_barrier @a memory_barrier. */ RTEMS_INLINE_ROUTINE void _Atomic_Fetch_and_int( volatile Atomic_Int *address, Atomic_Int value, Atomic_Memory_barrier memory_barrier ); RTEMS_INLINE_ROUTINE void _Atomic_Fetch_and_long( volatile Atomic_Long *address, Atomic_Long value, Atomic_Memory_barrier memory_barrier ); RTEMS_INLINE_ROUTINE void _Atomic_Fetch_and_ptr( volatile Atomic_Pointer *address, Atomic_Pointer value, Atomic_Memory_barrier memory_barrier ); RTEMS_INLINE_ROUTINE void _Atomic_Fetch_and_32( volatile Atomic_Int32 *address, Atomic_Int32 value, Atomic_Memory_barrier memory_barrier ); RTEMS_INLINE_ROUTINE void _Atomic_Fetch_and_64( volatile Atomic_Int64 *address, Atomic_Int64 value, Atomic_Memory_barrier memory_barrier ); /** * @brief Atomically compare the value stored at @a address with @a * old_value and if the two values are equal, update the value of @a * address with @a new_value. Returns zero if the compare failed, * nonzero otherwise. The operation uses a type of Atomic_Memory_barrier * @a memory_barrier. */ RTEMS_INLINE_ROUTINE int _Atomic_Compare_exchange_int( volatile Atomic_Int *address, Atomic_Int old_value, Atomic_Int new_value, Atomic_Memory_barrier memory_barrier ); RTEMS_INLINE_ROUTINE int _Atomic_Compare_exchange_long( volatile Atomic_Long *address, Atomic_Long old_value, Atomic_Long new_value, Atomic_Memory_barrier memory_barrier ); RTEMS_INLINE_ROUTINE int _Atomic_Compare_exchange_ptr( volatile Atomic_Pointer *address, Atomic_Pointer old_value, Atomic_Pointer new_value, Atomic_Memory_barrier memory_barrier ); RTEMS_INLINE_ROUTINE int _Atomic_Compare_exchange_32( volatile Atomic_Int32 *address, Atomic_Int32 old_value, Atomic_Int32 new_value, Atomic_Memory_barrier memory_barrier ); RTEMS_INLINE_ROUTINE int _Atomic_Compare_exchange_64( volatile Atomic_Int64 *address, Atomic_Int64 old_value, Atomic_Int64 new_value, Atomic_Memory_barrier memory_barrier ); #include #ifdef __cplusplus } #endif /**@}*/ #endif /* end of include file */