Pass core ID to critical nesting count macros (#1206)

* Pass core ID to CRITICAL_NESTING_COUNT macros

* Match existing data type for xCoreID

* Get core ID when interrupts are disabled

* Implement get core ID with interrupt disabled

* Get core ID inline within vTaskSuspendAll() to resolve compiler warning

* Fix formatting check

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>

---------

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
Co-authored-by: Ching-Hsin,Lee <chinglee@amazon.com>
Co-authored-by: Gaurav Aggarwal <aggarg@amazon.com>
Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com>
pull/1211/head
Felix van Oost 1 month ago committed by GitHub
parent e169442c29
commit 31dd1e39cb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -158,10 +158,10 @@ void vYieldCore( int xCoreID );
#define portCRITICAL_NESTING_IN_TCB 0 #define portCRITICAL_NESTING_IN_TCB 0
extern UBaseType_t uxCriticalNestings[ configNUMBER_OF_CORES ]; extern UBaseType_t uxCriticalNestings[ configNUMBER_OF_CORES ];
#define portGET_CRITICAL_NESTING_COUNT() ( uxCriticalNestings[ portGET_CORE_ID() ] ) #define portGET_CRITICAL_NESTING_COUNT( xCoreID ) ( uxCriticalNestings[ ( xCoreID ) ] )
#define portSET_CRITICAL_NESTING_COUNT( x ) ( uxCriticalNestings[ portGET_CORE_ID() ] = ( x ) ) #define portSET_CRITICAL_NESTING_COUNT( xCoreID, x ) ( uxCriticalNestings[ ( xCoreID ) ] = ( x ) )
#define portINCREMENT_CRITICAL_NESTING_COUNT() ( uxCriticalNestings[ portGET_CORE_ID() ]++ ) #define portINCREMENT_CRITICAL_NESTING_COUNT( xCoreID ) ( uxCriticalNestings[ ( xCoreID ) ]++ )
#define portDECREMENT_CRITICAL_NESTING_COUNT() ( uxCriticalNestings[ portGET_CORE_ID() ]-- ) #define portDECREMENT_CRITICAL_NESTING_COUNT( xCoreID ) ( uxCriticalNestings[ ( xCoreID ) ]-- )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

@ -317,10 +317,10 @@
#define taskATTRIBUTE_IS_IDLE ( UBaseType_t ) ( 1U << 0U ) #define taskATTRIBUTE_IS_IDLE ( UBaseType_t ) ( 1U << 0U )
#if ( ( configNUMBER_OF_CORES > 1 ) && ( portCRITICAL_NESTING_IN_TCB == 1 ) ) #if ( ( configNUMBER_OF_CORES > 1 ) && ( portCRITICAL_NESTING_IN_TCB == 1 ) )
#define portGET_CRITICAL_NESTING_COUNT() ( pxCurrentTCBs[ portGET_CORE_ID() ]->uxCriticalNesting ) #define portGET_CRITICAL_NESTING_COUNT( xCoreID ) ( pxCurrentTCBs[ ( xCoreID ) ]->uxCriticalNesting )
#define portSET_CRITICAL_NESTING_COUNT( x ) ( pxCurrentTCBs[ portGET_CORE_ID() ]->uxCriticalNesting = ( x ) ) #define portSET_CRITICAL_NESTING_COUNT( xCoreID, x ) ( pxCurrentTCBs[ ( xCoreID ) ]->uxCriticalNesting = ( x ) )
#define portINCREMENT_CRITICAL_NESTING_COUNT() ( pxCurrentTCBs[ portGET_CORE_ID() ]->uxCriticalNesting++ ) #define portINCREMENT_CRITICAL_NESTING_COUNT( xCoreID ) ( pxCurrentTCBs[ ( xCoreID ) ]->uxCriticalNesting++ )
#define portDECREMENT_CRITICAL_NESTING_COUNT() ( pxCurrentTCBs[ portGET_CORE_ID() ]->uxCriticalNesting-- ) #define portDECREMENT_CRITICAL_NESTING_COUNT( xCoreID ) ( pxCurrentTCBs[ ( xCoreID ) ]->uxCriticalNesting-- )
#endif /* #if ( ( configNUMBER_OF_CORES > 1 ) && ( portCRITICAL_NESTING_IN_TCB == 1 ) ) */ #endif /* #if ( ( configNUMBER_OF_CORES > 1 ) && ( portCRITICAL_NESTING_IN_TCB == 1 ) ) */
#define taskBITS_PER_BYTE ( ( size_t ) 8 ) #define taskBITS_PER_BYTE ( ( size_t ) 8 )
@ -807,13 +807,14 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
{ {
UBaseType_t uxPrevCriticalNesting; UBaseType_t uxPrevCriticalNesting;
const TCB_t * pxThisTCB; const TCB_t * pxThisTCB;
BaseType_t xCoreID = ( BaseType_t ) portGET_CORE_ID();
/* This must only be called from within a task. */ /* This must only be called from within a task. */
portASSERT_IF_IN_ISR(); portASSERT_IF_IN_ISR();
/* This function is always called with interrupts disabled /* This function is always called with interrupts disabled
* so this is safe. */ * so this is safe. */
pxThisTCB = pxCurrentTCBs[ portGET_CORE_ID() ]; pxThisTCB = pxCurrentTCBs[ xCoreID ];
while( pxThisTCB->xTaskRunState == taskTASK_SCHEDULED_TO_YIELD ) while( pxThisTCB->xTaskRunState == taskTASK_SCHEDULED_TO_YIELD )
{ {
@ -825,11 +826,11 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
* the suspension and critical nesting counts, as well as release * the suspension and critical nesting counts, as well as release
* and reacquire the correct locks. And then, do it all over again * and reacquire the correct locks. And then, do it all over again
* if our state changed again during the reacquisition. */ * if our state changed again during the reacquisition. */
uxPrevCriticalNesting = portGET_CRITICAL_NESTING_COUNT(); uxPrevCriticalNesting = portGET_CRITICAL_NESTING_COUNT( xCoreID );
if( uxPrevCriticalNesting > 0U ) if( uxPrevCriticalNesting > 0U )
{ {
portSET_CRITICAL_NESTING_COUNT( 0U ); portSET_CRITICAL_NESTING_COUNT( xCoreID, 0U );
portRELEASE_ISR_LOCK(); portRELEASE_ISR_LOCK();
} }
else else
@ -854,8 +855,9 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
portDISABLE_INTERRUPTS(); portDISABLE_INTERRUPTS();
portGET_TASK_LOCK(); portGET_TASK_LOCK();
portGET_ISR_LOCK(); portGET_ISR_LOCK();
xCoreID = ( BaseType_t ) portGET_CORE_ID();
portSET_CRITICAL_NESTING_COUNT( uxPrevCriticalNesting ); portSET_CRITICAL_NESTING_COUNT( xCoreID, uxPrevCriticalNesting );
if( uxPrevCriticalNesting == 0U ) if( uxPrevCriticalNesting == 0U )
{ {
@ -874,13 +876,14 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
BaseType_t xCurrentCoreTaskPriority; BaseType_t xCurrentCoreTaskPriority;
BaseType_t xLowestPriorityCore = ( BaseType_t ) -1; BaseType_t xLowestPriorityCore = ( BaseType_t ) -1;
BaseType_t xCoreID; BaseType_t xCoreID;
const BaseType_t xCurrentCoreID = portGET_CORE_ID();
#if ( configRUN_MULTIPLE_PRIORITIES == 0 ) #if ( configRUN_MULTIPLE_PRIORITIES == 0 )
BaseType_t xYieldCount = 0; BaseType_t xYieldCount = 0;
#endif /* #if ( configRUN_MULTIPLE_PRIORITIES == 0 ) */ #endif /* #if ( configRUN_MULTIPLE_PRIORITIES == 0 ) */
/* This must be called from a critical section. */ /* This must be called from a critical section. */
configASSERT( portGET_CRITICAL_NESTING_COUNT() > 0U ); configASSERT( portGET_CRITICAL_NESTING_COUNT( xCurrentCoreID ) > 0U );
#if ( configRUN_MULTIPLE_PRIORITIES == 0 ) #if ( configRUN_MULTIPLE_PRIORITIES == 0 )
@ -969,11 +972,11 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
#if ( configRUN_MULTIPLE_PRIORITIES == 0 ) #if ( configRUN_MULTIPLE_PRIORITIES == 0 )
/* Verify that the calling core always yields to higher priority tasks. */ /* Verify that the calling core always yields to higher priority tasks. */
if( ( ( pxCurrentTCBs[ portGET_CORE_ID() ]->uxTaskAttributes & taskATTRIBUTE_IS_IDLE ) == 0U ) && if( ( ( pxCurrentTCBs[ xCurrentCoreID ]->uxTaskAttributes & taskATTRIBUTE_IS_IDLE ) == 0U ) &&
( pxTCB->uxPriority > pxCurrentTCBs[ portGET_CORE_ID() ]->uxPriority ) ) ( pxTCB->uxPriority > pxCurrentTCBs[ xCurrentCoreID ]->uxPriority ) )
{ {
configASSERT( ( xYieldPendings[ portGET_CORE_ID() ] == pdTRUE ) || configASSERT( ( xYieldPendings[ xCurrentCoreID ] == pdTRUE ) ||
( taskTASK_IS_RUNNING( pxCurrentTCBs[ portGET_CORE_ID() ] ) == pdFALSE ) ); ( taskTASK_IS_RUNNING( pxCurrentTCBs[ xCurrentCoreID ] ) == pdFALSE ) );
} }
#endif #endif
} }
@ -3880,7 +3883,7 @@ void vTaskSuspendAll( void )
ulState = portSET_INTERRUPT_MASK(); ulState = portSET_INTERRUPT_MASK();
/* This must never be called from inside a critical section. */ /* This must never be called from inside a critical section. */
configASSERT( portGET_CRITICAL_NESTING_COUNT() == 0 ); configASSERT( portGET_CRITICAL_NESTING_COUNT( portGET_CORE_ID() ) == 0 );
/* portSOFTWARE_BARRIER() is only implemented for emulated/simulated ports that /* portSOFTWARE_BARRIER() is only implemented for emulated/simulated ports that
* do not otherwise exhibit real time behaviour. */ * do not otherwise exhibit real time behaviour. */
@ -4003,8 +4006,7 @@ BaseType_t xTaskResumeAll( void )
* tasks from this list into their appropriate ready list. */ * tasks from this list into their appropriate ready list. */
taskENTER_CRITICAL(); taskENTER_CRITICAL();
{ {
BaseType_t xCoreID; const BaseType_t xCoreID = ( BaseType_t ) portGET_CORE_ID();
xCoreID = ( BaseType_t ) portGET_CORE_ID();
/* If uxSchedulerSuspended is zero then this function does not match a /* If uxSchedulerSuspended is zero then this function does not match a
* previous call to vTaskSuspendAll(). */ * previous call to vTaskSuspendAll(). */
@ -5187,7 +5189,7 @@ BaseType_t xTaskIncrementTick( void )
/* vTaskSwitchContext() must never be called from within a critical section. /* vTaskSwitchContext() must never be called from within a critical section.
* This is not necessarily true for single core FreeRTOS, but it is for this * This is not necessarily true for single core FreeRTOS, but it is for this
* SMP port. */ * SMP port. */
configASSERT( portGET_CRITICAL_NESTING_COUNT() == 0 ); configASSERT( portGET_CRITICAL_NESTING_COUNT( xCoreID ) == 0 );
if( uxSchedulerSuspended != ( UBaseType_t ) 0U ) if( uxSchedulerSuspended != ( UBaseType_t ) 0U )
{ {
@ -6937,16 +6939,24 @@ static void prvResetNextTaskUnblockTime( void )
*/ */
void vTaskYieldWithinAPI( void ) void vTaskYieldWithinAPI( void )
{ {
UBaseType_t ulState;
traceENTER_vTaskYieldWithinAPI(); traceENTER_vTaskYieldWithinAPI();
if( portGET_CRITICAL_NESTING_COUNT() == 0U ) ulState = portSET_INTERRUPT_MASK();
{
portYIELD();
}
else
{ {
xYieldPendings[ portGET_CORE_ID() ] = pdTRUE; const BaseType_t xCoreID = ( BaseType_t ) portGET_CORE_ID();
if( portGET_CRITICAL_NESTING_COUNT( xCoreID ) == 0U )
{
portYIELD();
}
else
{
xYieldPendings[ xCoreID ] = pdTRUE;
}
} }
portCLEAR_INTERRUPT_MASK( ulState );
traceRETURN_vTaskYieldWithinAPI(); traceRETURN_vTaskYieldWithinAPI();
} }
@ -6995,40 +7005,43 @@ static void prvResetNextTaskUnblockTime( void )
traceENTER_vTaskEnterCritical(); traceENTER_vTaskEnterCritical();
portDISABLE_INTERRUPTS(); portDISABLE_INTERRUPTS();
if( xSchedulerRunning != pdFALSE )
{ {
if( portGET_CRITICAL_NESTING_COUNT() == 0U ) const BaseType_t xCoreID = ( BaseType_t ) portGET_CORE_ID();
{
portGET_TASK_LOCK();
portGET_ISR_LOCK();
}
portINCREMENT_CRITICAL_NESTING_COUNT();
/* This is not the interrupt safe version of the enter critical if( xSchedulerRunning != pdFALSE )
* function so assert() if it is being called from an interrupt
* context. Only API functions that end in "FromISR" can be used in an
* interrupt. Only assert if the critical nesting count is 1 to
* protect against recursive calls if the assert function also uses a
* critical section. */
if( portGET_CRITICAL_NESTING_COUNT() == 1U )
{ {
portASSERT_IF_IN_ISR(); if( portGET_CRITICAL_NESTING_COUNT( xCoreID ) == 0U )
{
portGET_TASK_LOCK();
portGET_ISR_LOCK();
}
if( uxSchedulerSuspended == 0U ) portINCREMENT_CRITICAL_NESTING_COUNT( xCoreID );
/* This is not the interrupt safe version of the enter critical
* function so assert() if it is being called from an interrupt
* context. Only API functions that end in "FromISR" can be used in an
* interrupt. Only assert if the critical nesting count is 1 to
* protect against recursive calls if the assert function also uses a
* critical section. */
if( portGET_CRITICAL_NESTING_COUNT( xCoreID ) == 1U )
{ {
/* The only time there would be a problem is if this is called portASSERT_IF_IN_ISR();
* before a context switch and vTaskExitCritical() is called
* after pxCurrentTCB changes. Therefore this should not be if( uxSchedulerSuspended == 0U )
* used within vTaskSwitchContext(). */ {
prvCheckForRunStateChange(); /* The only time there would be a problem is if this is called
* before a context switch and vTaskExitCritical() is called
* after pxCurrentTCB changes. Therefore this should not be
* used within vTaskSwitchContext(). */
prvCheckForRunStateChange();
}
} }
} }
} else
else {
{ mtCOVERAGE_TEST_MARKER();
mtCOVERAGE_TEST_MARKER(); }
} }
traceRETURN_vTaskEnterCritical(); traceRETURN_vTaskEnterCritical();
@ -7043,6 +7056,7 @@ static void prvResetNextTaskUnblockTime( void )
UBaseType_t vTaskEnterCriticalFromISR( void ) UBaseType_t vTaskEnterCriticalFromISR( void )
{ {
UBaseType_t uxSavedInterruptStatus = 0; UBaseType_t uxSavedInterruptStatus = 0;
const BaseType_t xCoreID = ( BaseType_t ) portGET_CORE_ID();
traceENTER_vTaskEnterCriticalFromISR(); traceENTER_vTaskEnterCriticalFromISR();
@ -7050,12 +7064,12 @@ static void prvResetNextTaskUnblockTime( void )
{ {
uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
if( portGET_CRITICAL_NESTING_COUNT() == 0U ) if( portGET_CRITICAL_NESTING_COUNT( xCoreID ) == 0U )
{ {
portGET_ISR_LOCK(); portGET_ISR_LOCK();
} }
portINCREMENT_CRITICAL_NESTING_COUNT(); portINCREMENT_CRITICAL_NESTING_COUNT( xCoreID );
} }
else else
{ {
@ -7119,28 +7133,30 @@ static void prvResetNextTaskUnblockTime( void )
void vTaskExitCritical( void ) void vTaskExitCritical( void )
{ {
const BaseType_t xCoreID = ( BaseType_t ) portGET_CORE_ID();
traceENTER_vTaskExitCritical(); traceENTER_vTaskExitCritical();
if( xSchedulerRunning != pdFALSE ) if( xSchedulerRunning != pdFALSE )
{ {
/* If critical nesting count is zero then this function /* If critical nesting count is zero then this function
* does not match a previous call to vTaskEnterCritical(). */ * does not match a previous call to vTaskEnterCritical(). */
configASSERT( portGET_CRITICAL_NESTING_COUNT() > 0U ); configASSERT( portGET_CRITICAL_NESTING_COUNT( xCoreID ) > 0U );
/* This function should not be called in ISR. Use vTaskExitCriticalFromISR /* This function should not be called in ISR. Use vTaskExitCriticalFromISR
* to exit critical section from ISR. */ * to exit critical section from ISR. */
portASSERT_IF_IN_ISR(); portASSERT_IF_IN_ISR();
if( portGET_CRITICAL_NESTING_COUNT() > 0U ) if( portGET_CRITICAL_NESTING_COUNT( xCoreID ) > 0U )
{ {
portDECREMENT_CRITICAL_NESTING_COUNT(); portDECREMENT_CRITICAL_NESTING_COUNT( xCoreID );
if( portGET_CRITICAL_NESTING_COUNT() == 0U ) if( portGET_CRITICAL_NESTING_COUNT( xCoreID ) == 0U )
{ {
BaseType_t xYieldCurrentTask; BaseType_t xYieldCurrentTask;
/* Get the xYieldPending stats inside the critical section. */ /* Get the xYieldPending stats inside the critical section. */
xYieldCurrentTask = xYieldPendings[ portGET_CORE_ID() ]; xYieldCurrentTask = xYieldPendings[ xCoreID ];
portRELEASE_ISR_LOCK(); portRELEASE_ISR_LOCK();
portRELEASE_TASK_LOCK(); portRELEASE_TASK_LOCK();
@ -7180,19 +7196,23 @@ static void prvResetNextTaskUnblockTime( void )
void vTaskExitCriticalFromISR( UBaseType_t uxSavedInterruptStatus ) void vTaskExitCriticalFromISR( UBaseType_t uxSavedInterruptStatus )
{ {
BaseType_t xCoreID;
traceENTER_vTaskExitCriticalFromISR( uxSavedInterruptStatus ); traceENTER_vTaskExitCriticalFromISR( uxSavedInterruptStatus );
if( xSchedulerRunning != pdFALSE ) if( xSchedulerRunning != pdFALSE )
{ {
xCoreID = ( BaseType_t ) portGET_CORE_ID();
/* If critical nesting count is zero then this function /* If critical nesting count is zero then this function
* does not match a previous call to vTaskEnterCritical(). */ * does not match a previous call to vTaskEnterCritical(). */
configASSERT( portGET_CRITICAL_NESTING_COUNT() > 0U ); configASSERT( portGET_CRITICAL_NESTING_COUNT( xCoreID ) > 0U );
if( portGET_CRITICAL_NESTING_COUNT() > 0U ) if( portGET_CRITICAL_NESTING_COUNT( xCoreID ) > 0U )
{ {
portDECREMENT_CRITICAL_NESTING_COUNT(); portDECREMENT_CRITICAL_NESTING_COUNT( xCoreID );
if( portGET_CRITICAL_NESTING_COUNT() == 0U ) if( portGET_CRITICAL_NESTING_COUNT( xCoreID ) == 0U )
{ {
portRELEASE_ISR_LOCK(); portRELEASE_ISR_LOCK();
portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );

Loading…
Cancel
Save