mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-08-19 01:28:32 -04:00
Update to the latest atomic.h.
Improve commenting in RISC-V GCC port. Fix IAR RISC-V port so the first task starts with interrupts enabled. Add references to third party page ref using newlib with FreeRTOS into the tasks.c file in each place newlib is referenced. Move the position of the traceTASK_DELETE() trace macro in case of use with a memory allocator that writes over freed memory even when inside a critical section. Efficiency improvement: Make sure xTaskIncrementTick() does not return pdTRUE when the scheduler is locked. This just prevents an unnecessary yield interrupt (unnecessary as it is ignored) when xYieldPending happens to be pdTRUE.
This commit is contained in:
parent
18916d5820
commit
16639d2d63
7 changed files with 206 additions and 178 deletions
|
@ -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.
|
||||
* Implementations 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] pDestination 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] pulDestination 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 *pDestination with ulExchange, if previous
|
||||
* *pDestination value equals ulComparand.
|
||||
* @note This function only swaps *pulDestination with ulExchange, if previous
|
||||
* *pulDestination 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 *ppDestination to the value
|
||||
* of *pExchange.
|
||||
* @brief Atomically sets the address pointed to by *ppvDestination to the value
|
||||
* of *pvExchange.
|
||||
*
|
||||
* @param[in, out] ppDestination Pointer to memory location from where a pointer
|
||||
* value is to be loaded and written back to.
|
||||
* @param[in] pExchange Pointer value to be written to *ppDestination.
|
||||
* @param[in, out] ppvDestination Pointer to memory location from where a pointer
|
||||
* value is to be loaded and written back to.
|
||||
* @param[in] pvExchange Pointer value to be written to *ppvDestination.
|
||||
*
|
||||
* @return The initial value of *ppDestination.
|
||||
* @return The initial value of *ppvDestination.
|
||||
*/
|
||||
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] ppDestination Pointer to memory location from where a pointer
|
||||
* value is to be loaded and checked.
|
||||
* @param[in] pExchange If condition meets, write this value to memory.
|
||||
* @param[in] pComparand Swap condition.
|
||||
* @param[in, out] ppvDestination Pointer to memory location from where a pointer
|
||||
* value is to be loaded and checked.
|
||||
* @param[in] pvExchange If condition meets, write this value to memory.
|
||||
* @param[in] pvComparand Swap condition.
|
||||
*
|
||||
* @return Unsigned integer of value 1 or 0. 1 for swapped, 0 for not swapped.
|
||||
*
|
||||
* @note This function only swaps *ppDestination with pExchange, if previous
|
||||
* *ppDestination value equals pComparand.
|
||||
* @note This function only swaps *ppvDestination with pvExchange, if previous
|
||||
* *ppvDestination value equals pvComparand.
|
||||
*/
|
||||
static portFORCE_INLINE uint32_t Atomic_CompareAndSwapPointers_p32(
|
||||
void * volatile * ppDestination,
|
||||
void * pExchange, void * pComparand )
|
||||
static portFORCE_INLINE uint32_t Atomic_CompareAndSwapPointers_p32( void * volatile * ppvDestination,
|
||||
void * pvExchange,
|
||||
void * pvComparand )
|
||||
{
|
||||
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] pAddend Pointer to memory location from where value is to be
|
||||
* loaded and written back to.
|
||||
* @param[in] ulCount Value to be added to *pAddend.
|
||||
* @param[in,out] pulAddend Pointer to memory location from where value is to be
|
||||
* loaded and written back to.
|
||||
* @param[in] ulCount Value to be added to *pulAddend.
|
||||
*
|
||||
* @return previous *pAddend value.
|
||||
* @return previous *pulAddend 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] pAddend Pointer to memory location from where value is to be
|
||||
* loaded and written back to.
|
||||
* @param[in] ulCount Value to be subtract from *pAddend.
|
||||
* @param[in,out] pulAddend Pointer to memory location from where value is to be
|
||||
* loaded and written back to.
|
||||
* @param[in] ulCount Value to be subtract from *pulAddend.
|
||||
*
|
||||
* @return previous *pAddend value.
|
||||
* @return previous *pulAddend 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] pAddend Pointer to memory location from where value is to be
|
||||
* loaded and written back to.
|
||||
* @param[in,out] pulAddend Pointer to memory location from where value is to be
|
||||
* loaded and written back to.
|
||||
*
|
||||
* @return *pAddend value before increment.
|
||||
* @return *pulAddend value before increment.
|
||||
*/
|
||||
static portFORCE_INLINE uint32_t Atomic_Increment_u32( uint32_t volatile * pAddend )
|
||||
static portFORCE_INLINE uint32_t Atomic_Increment_u32( uint32_t volatile * pulAddend )
|
||||
{
|
||||
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] pAddend Pointer to memory location from where value is to be
|
||||
* loaded and written back to.
|
||||
* @param[in,out] pulAddend Pointer to memory location from where value is to be
|
||||
* loaded and written back to.
|
||||
*
|
||||
* @return *pAddend value before decrement.
|
||||
* @return *pulAddend value before decrement.
|
||||
*/
|
||||
static portFORCE_INLINE uint32_t Atomic_Decrement_u32( uint32_t volatile * pAddend )
|
||||
static portFORCE_INLINE uint32_t Atomic_Decrement_u32( uint32_t volatile * pulAddend )
|
||||
{
|
||||
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] pDestination Pointer to memory location from where value is
|
||||
* to be loaded and written back to.
|
||||
* @param [in] ulValue Value to be ORed with *pDestination.
|
||||
* @param [in, out] pulDestination Pointer to memory location from where value is
|
||||
* to be loaded and written back to.
|
||||
* @param [in] ulValue Value to be ORed with *pulDestination.
|
||||
*
|
||||
* @return The original value of *pDestination.
|
||||
* @return The original value of *pulDestination.
|
||||
*/
|
||||
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] pDestination Pointer to memory location from where value is
|
||||
* to be loaded and written back to.
|
||||
* @param [in] ulValue Value to be ANDed with *pDestination.
|
||||
* @param [in, out] pulDestination Pointer to memory location from where value is
|
||||
* to be loaded and written back to.
|
||||
* @param [in] ulValue Value to be ANDed with *pulDestination.
|
||||
*
|
||||
* @return The original value of *pDestination.
|
||||
* @return The original value of *pulDestination.
|
||||
*/
|
||||
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] pDestination Pointer to memory location from where value is
|
||||
* to be loaded and written back to.
|
||||
* @param [in] ulValue Value to be NANDed with *pDestination.
|
||||
* @param [in, out] pulDestination Pointer to memory location from where value is
|
||||
* to be loaded and written back to.
|
||||
* @param [in] ulValue Value to be NANDed with *pulDestination.
|
||||
*
|
||||
* @return The original value of *pDestination.
|
||||
* @return The original value of *pulDestination.
|
||||
*/
|
||||
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] pDestination Pointer to memory location from where value is
|
||||
* to be loaded and written back to.
|
||||
* @param [in] ulValue Value to be XORed with *pDestination.
|
||||
* @param [in, out] pulDestination Pointer to memory location from where value is
|
||||
* to be loaded and written back to.
|
||||
* @param [in] ulValue Value to be XORed with *pulDestination.
|
||||
*
|
||||
* @return The original value of *pDestination.
|
||||
* @return The original value of *pulDestination.
|
||||
*/
|
||||
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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue