@ -29,9 +29,9 @@
* @ file atomic . h
* @ brief FreeRTOS atomic operation support .
*
* This file implements atomic by disabling interrupts globally .
* Implementation with architecture specific atomic instructions
* are to be provided under each compiler directory .
* This file implements atomic functions by disabling interrupts globally .
* Implementation s with architecture specific atomic instructions can be
* provided under each compiler directory .
*/
# ifndef ATOMIC_H
@ -48,12 +48,14 @@
extern " C " {
# endif
/* Port specific definitions -- entering/exiting critical section.
/*
* Port specific definitions - - entering / exiting critical section .
* Refer template - - . / lib / FreeRTOS / portable / Compiler / Arch / portmacro . h
*
* Every call to ATOMIC_EXIT_CRITICAL ( ) must be closely paired with
* ATOMIC_ENTER_CRITICAL ( ) .
* */
*
*/
# if defined( portSET_INTERRUPT_MASK_FROM_ISR )
/* Nested interrupt scheme is supported in this port. */
@ -71,11 +73,12 @@ extern "C" {
# endif /* portSET_INTERRUPT_MASK_FROM_ISR() */
/* Port specific definition -- "always inline".
* Inline is compiler specific , and may not always get inlined depending on your optimization level .
* Also , inline is considerred as performance optimization for atomic .
* Thus , if portFORCE_INLINE is not provided by portmacro . h , instead of resulting error ,
* simply define it .
/*
* Port specific definition - - " always inline " .
* Inline is compiler specific , and may not always get inlined depending on your
* optimization level . Also , inline is considered as performance optimization
* for atomic . Thus , if portFORCE_INLINE is not provided by portmacro . h ,
* instead of resulting error , simply define it away .
*/
# ifndef portFORCE_INLINE
# define portFORCE_INLINE
@ -91,97 +94,98 @@ extern "C" {
*
* @ brief Performs an atomic compare - and - swap operation on the specified values .
*
* @ param [ in , out ] p Destination Pointer to memory location from where value is
* to be loaded and checked .
* @ param [ in ] ulExchange If condition meets , write this value to memory .
* @ param [ in ] ulComparand Swap condition .
* @ param [ in , out ] p ul Destination Pointer to memory location from where value is
* to be loaded and checked .
* @ param [ in ] ulExchange If condition meets , write this value to memory .
* @ param [ in ] ulComparand Swap condition .
*
* @ return Unsigned integer of value 1 or 0. 1 for swapped , 0 for not swapped .
*
* @ note This function only swaps * p Destination with ulExchange , if previous
* * p Destination value equals ulComparand .
* @ note This function only swaps * p ul Destination with ulExchange , if previous
* * pul Destination value equals ulComparand .
*/
static portFORCE_INLINE uint32_t Atomic_CompareAndSwap_u32 (
uint32_t volatile * pDestination ,
uint32_t ulExchange ,
uint32_t ulComparand )
static portFORCE_INLINE uint32_t Atomic_CompareAndSwap_u32 ( uint32_t volatile * pulDestination ,
uint32_t ulExchange ,
uint32_t ulComparand )
{
uint32_t ulReturnValue = ATOMIC_COMPARE_AND_SWAP_FAILURE ;
uint32_t ulReturnValue ;
ATOMIC_ENTER_CRITICAL ( ) ;
if ( * pDestination = = ulComparand )
{
* pDestination = ulExchange ;
ulReturnValue = ATOMIC_COMPARE_AND_SWAP_SUCCESS ;
if ( * pulDestination = = ulComparand )
{
* pulDestination = ulExchange ;
ulReturnValue = ATOMIC_COMPARE_AND_SWAP_SUCCESS ;
}
else
{
ulReturnValue = ATOMIC_COMPARE_AND_SWAP_FAILURE ;
}
}
ATOMIC_EXIT_CRITICAL ( ) ;
return ulReturnValue ;
}
/*-----------------------------------------------------------*/
/**
* Atomic swap ( pointers )
*
* @ brief Atomically sets the address pointed to by * pp Destination to the value
* of * p Exchange.
* @ brief Atomically sets the address pointed to by * pp v Destination to the value
* of * pv Exchange.
*
* @ param [ in , out ] pp Destination Pointer to memory location from where a pointer
* value is to be loaded and written back to .
* @ param [ in ] p Exchange Pointer value to be written to * pp Destination.
* @ param [ in , out ] pp v Destination Pointer to memory location from where a pointer
* value is to be loaded and written back to .
* @ param [ in ] p vExchange Pointer value to be written to * pp v Destination.
*
* @ return The initial value of * pp Destination.
* @ return The initial value of * pp v Destination.
*/
static portFORCE_INLINE void * Atomic_SwapPointers_p32 (
void * volatile * ppDestination ,
void * pExchange )
static portFORCE_INLINE void * Atomic_SwapPointers_p32 ( void * volatile * ppvDestination ,
void * pvExchange )
{
void * pReturnValue ;
void * pReturnValue ;
ATOMIC_ENTER_CRITICAL ( ) ;
pReturnValue = * ppDestination ;
* ppDestination = pExchange ;
{
pReturnValue = * ppvDestination ;
* ppvDestination = pvExchange ;
}
ATOMIC_EXIT_CRITICAL ( ) ;
return pReturnValue ;
}
/*-----------------------------------------------------------*/
/**
* Atomic compare - and - swap ( pointers )
*
* @ brief Performs an atomic compare - and - swap operation on the specified pointer
* values .
* values .
*
* @ param [ in , out ] pp Destination Pointer to memory location from where a pointer
* value is to be loaded and checked .
* @ param [ in ] p Exchange If condition meets , write this value to memory .
* @ param [ in ] p Comparand Swap condition .
* @ param [ in , out ] pp v Destination Pointer to memory location from where a pointer
* value is to be loaded and checked .
* @ param [ in ] p vExchange If condition meets , write this value to memory .
* @ param [ in ] p vComparand Swap condition .
*
* @ return Unsigned integer of value 1 or 0. 1 for swapped , 0 for not swapped .
*
* @ note This function only swaps * pp Destination with p Exchange, if previous
* * pp Destination value equals p Comparand.
* @ note This function only swaps * pp v Destination with p v Exchange, if previous
* * ppv Destination value equals p v Comparand.
*/
static portFORCE_INLINE uint32_t Atomic_CompareAndSwapPointers_p32 (
void * volatile * ppDestination ,
void * p Exchange, void * p Comparand )
static portFORCE_INLINE uint32_t Atomic_CompareAndSwapPointers_p32 ( void * volatile * ppvDestination ,
void * pvExchange ,
void * p vComparand )
{
uint32_t ulReturnValue = ATOMIC_COMPARE_AND_SWAP_FAILURE ;
uint32_t ulReturnValue = ATOMIC_COMPARE_AND_SWAP_FAILURE ;
ATOMIC_ENTER_CRITICAL ( ) ;
if ( * ppDestination = = pComparand )
{
* ppDestination = pExchange ;
ulReturnValue = ATOMIC_COMPARE_AND_SWAP_SUCCESS ;
if ( * ppvDestination = = pvComparand )
{
* ppvDestination = pvExchange ;
ulReturnValue = ATOMIC_COMPARE_AND_SWAP_SUCCESS ;
}
}
ATOMIC_EXIT_CRITICAL ( ) ;
return ulReturnValue ;
@ -195,103 +199,100 @@ static portFORCE_INLINE uint32_t Atomic_CompareAndSwapPointers_p32(
*
* @ brief Atomically adds count to the value of the specified pointer points to .
*
* @ param [ in , out ] p Addend Pointer to memory location from where value is to be
* loaded and written back to .
* @ param [ in ] ulCount Value to be added to * p Addend.
* @ param [ in , out ] p ul Addend Pointer to memory location from where value is to be
* loaded and written back to .
* @ param [ in ] ulCount Value to be added to * p ul Addend.
*
* @ return previous * p Addend value .
* @ return previous * p ul Addend value .
*/
static portFORCE_INLINE uint32_t Atomic_Add_u32 (
uint32_t volatile * pAddend ,
uint32_t ulCount )
static portFORCE_INLINE uint32_t Atomic_Add_u32 ( uint32_t volatile * pulAddend ,
uint32_t ulCount )
{
uint32_t ulCurrent ;
ATOMIC_ENTER_CRITICAL ( ) ;
ulCurrent = * pAddend ;
* pAddend + = ulCount ;
{
ulCurrent = * pulAddend ;
* pulAddend + = ulCount ;
}
ATOMIC_EXIT_CRITICAL ( ) ;
return ulCurrent ;
}
/*-----------------------------------------------------------*/
/**
* Atomic subtract
*
* @ brief Atomically subtracts count from the value of the specified pointer
* pointers to .
* pointers to .
*
* @ param [ in , out ] p Addend Pointer to memory location from where value is to be
* loaded and written back to .
* @ param [ in ] ulCount Value to be subtract from * p Addend.
* @ param [ in , out ] p ul Addend Pointer to memory location from where value is to be
* loaded and written back to .
* @ param [ in ] ulCount Value to be subtract from * p ul Addend.
*
* @ return previous * p Addend value .
* @ return previous * p ul Addend value .
*/
static portFORCE_INLINE uint32_t Atomic_Subtract_u32 (
uint32_t volatile * pAddend ,
uint32_t ulCount )
static portFORCE_INLINE uint32_t Atomic_Subtract_u32 ( uint32_t volatile * pulAddend ,
uint32_t ulCount )
{
uint32_t ulCurrent ;
ATOMIC_ENTER_CRITICAL ( ) ;
ulCurrent = * pAddend ;
* pAddend - = ulCount ;
{
ulCurrent = * pulAddend ;
* pulAddend - = ulCount ;
}
ATOMIC_EXIT_CRITICAL ( ) ;
return ulCurrent ;
}
/*-----------------------------------------------------------*/
/**
* Atomic increment
*
* @ brief Atomically increments the value of the specified pointer points to .
*
* @ param [ in , out ] p Addend Pointer to memory location from where value is to be
* loaded and written back to .
* @ param [ in , out ] p ul Addend Pointer to memory location from where value is to be
* loaded and written back to .
*
* @ return * p Addend value before increment .
* @ return * p ul Addend value before increment .
*/
static portFORCE_INLINE uint32_t Atomic_Increment_u32 ( uint32_t volatile * p Addend )
static portFORCE_INLINE uint32_t Atomic_Increment_u32 ( uint32_t volatile * p ul Addend )
{
uint32_t ulCurrent ;
uint32_t ulCurrent ;
ATOMIC_ENTER_CRITICAL ( ) ;
ulCurrent = * pAddend ;
* pAddend + = 1 ;
{
ulCurrent = * pulAddend ;
* pulAddend + = 1 ;
}
ATOMIC_EXIT_CRITICAL ( ) ;
return ulCurrent ;
}
/*-----------------------------------------------------------*/
/**
* Atomic decrement
*
* @ brief Atomically decrements the value of the specified pointer points to
*
* @ param [ in , out ] p Addend Pointer to memory location from where value is to be
* loaded and written back to .
* @ param [ in , out ] p ul Addend Pointer to memory location from where value is to be
* loaded and written back to .
*
* @ return * p Addend value before decrement .
* @ return * p ul Addend value before decrement .
*/
static portFORCE_INLINE uint32_t Atomic_Decrement_u32 ( uint32_t volatile * p Addend )
static portFORCE_INLINE uint32_t Atomic_Decrement_u32 ( uint32_t volatile * p ul Addend )
{
uint32_t ulCurrent ;
uint32_t ulCurrent ;
ATOMIC_ENTER_CRITICAL ( ) ;
ulCurrent = * pAddend ;
* pAddend - = 1 ;
{
ulCurrent = * pulAddend ;
* pulAddend - = 1 ;
}
ATOMIC_EXIT_CRITICAL ( ) ;
return ulCurrent ;
@ -304,108 +305,103 @@ static portFORCE_INLINE uint32_t Atomic_Decrement_u32( uint32_t volatile * pAdde
*
* @ brief Performs an atomic OR operation on the specified values .
*
* @ param [ in , out ] p Destination Pointer to memory location from where value is
* to be loaded and written back to .
* @ param [ in ] ulValue Value to be ORed with * p Destination.
* @ param [ in , out ] p ul Destination Pointer to memory location from where value is
* to be loaded and written back to .
* @ param [ in ] ulValue Value to be ORed with * p ul Destination.
*
* @ return The original value of * p Destination.
* @ return The original value of * p ul Destination.
*/
static portFORCE_INLINE uint32_t Atomic_OR_u32 (
uint32_t volatile * pDestination ,
uint32_t ulValue )
static portFORCE_INLINE uint32_t Atomic_OR_u32 ( uint32_t volatile * pulDestination ,
uint32_t ulValue )
{
uint32_t ulCurrent ;
uint32_t ulCurrent ;
ATOMIC_ENTER_CRITICAL ( ) ;
ulCurrent = * pDestination ;
* pDestination | = ulValue ;
{
ulCurrent = * pulDestination ;
* pulDestination | = ulValue ;
}
ATOMIC_EXIT_CRITICAL ( ) ;
return ulCurrent ;
}
/*-----------------------------------------------------------*/
/**
* Atomic AND
*
* @ brief Performs an atomic AND operation on the specified values .
*
* @ param [ in , out ] p Destination Pointer to memory location from where value is
* to be loaded and written back to .
* @ param [ in ] ulValue Value to be ANDed with * p Destination.
* @ param [ in , out ] p ul Destination Pointer to memory location from where value is
* to be loaded and written back to .
* @ param [ in ] ulValue Value to be ANDed with * p ul Destination.
*
* @ return The original value of * p Destination.
* @ return The original value of * p ul Destination.
*/
static portFORCE_INLINE uint32_t Atomic_AND_u32 (
uint32_t volatile * pDestination ,
uint32_t ulValue )
static portFORCE_INLINE uint32_t Atomic_AND_u32 ( uint32_t volatile * pulDestination ,
uint32_t ulValue )
{
uint32_t ulCurrent ;
uint32_t ulCurrent ;
ATOMIC_ENTER_CRITICAL ( ) ;
ulCurrent = * pDestination ;
* pDestination & = ulValue ;
{
ulCurrent = * pulDestination ;
* pulDestination & = ulValue ;
}
ATOMIC_EXIT_CRITICAL ( ) ;
return ulCurrent ;
}
/*-----------------------------------------------------------*/
/**
* Atomic NAND
*
* @ brief Performs an atomic NAND operation on the specified values .
*
* @ param [ in , out ] p Destination Pointer to memory location from where value is
* to be loaded and written back to .
* @ param [ in ] ulValue Value to be NANDed with * p Destination.
* @ param [ in , out ] p ul Destination Pointer to memory location from where value is
* to be loaded and written back to .
* @ param [ in ] ulValue Value to be NANDed with * p ul Destination.
*
* @ return The original value of * p Destination.
* @ return The original value of * p ul Destination.
*/
static portFORCE_INLINE uint32_t Atomic_NAND_u32 (
uint32_t volatile * pDestination ,
uint32_t ulValue )
static portFORCE_INLINE uint32_t Atomic_NAND_u32 ( uint32_t volatile * pulDestination ,
uint32_t ulValue )
{
uint32_t ulCurrent ;
uint32_t ulCurrent ;
ATOMIC_ENTER_CRITICAL ( ) ;
ulCurrent = * pDestination ;
* pDestination = ~ ( ulCurrent & ulValue ) ;
{
ulCurrent = * pulDestination ;
* pulDestination = ~ ( ulCurrent & ulValue ) ;
}
ATOMIC_EXIT_CRITICAL ( ) ;
return ulCurrent ;
}
/*-----------------------------------------------------------*/
/**
* Atomic XOR
*
* @ brief Performs an atomic XOR operation on the specified values .
*
* @ param [ in , out ] p Destination Pointer to memory location from where value is
* to be loaded and written back to .
* @ param [ in ] ulValue Value to be XORed with * p Destination.
* @ param [ in , out ] p ul Destination Pointer to memory location from where value is
* to be loaded and written back to .
* @ param [ in ] ulValue Value to be XORed with * p ul Destination.
*
* @ return The original value of * p Destination.
* @ return The original value of * p ul Destination.
*/
static portFORCE_INLINE uint32_t Atomic_XOR_u32 (
uint32_t volatile * pDestination ,
uint32_t ulValue )
static portFORCE_INLINE uint32_t Atomic_XOR_u32 ( uint32_t volatile * pulDestination ,
uint32_t ulValue )
{
uint32_t ulCurrent ;
uint32_t ulCurrent ;
ATOMIC_ENTER_CRITICAL ( ) ;
ulCurrent = * pDestination ;
* pDestination ^ = ulValue ;
{
ulCurrent = * pulDestination ;
* pulDestination ^ = ulValue ;
}
ATOMIC_EXIT_CRITICAL ( ) ;
return ulCurrent ;