Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pass core ID to critical nesting count macros #1206

8 changes: 4 additions & 4 deletions portable/ThirdParty/GCC/RP2040/include/portmacro.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,10 +158,10 @@ void vYieldCore( int xCoreID );
#define portCRITICAL_NESTING_IN_TCB 0

extern UBaseType_t uxCriticalNestings[ configNUMBER_OF_CORES ];
#define portGET_CRITICAL_NESTING_COUNT() ( uxCriticalNestings[ portGET_CORE_ID() ] )
#define portSET_CRITICAL_NESTING_COUNT( x ) ( uxCriticalNestings[ portGET_CORE_ID() ] = ( x ) )
#define portINCREMENT_CRITICAL_NESTING_COUNT() ( uxCriticalNestings[ portGET_CORE_ID() ]++ )
#define portDECREMENT_CRITICAL_NESTING_COUNT() ( uxCriticalNestings[ portGET_CORE_ID() ]-- )
#define portGET_CRITICAL_NESTING_COUNT( xCoreID ) ( uxCriticalNestings[ ( xCoreID ) ] )
#define portSET_CRITICAL_NESTING_COUNT( xCoreID, x ) ( uxCriticalNestings[ ( xCoreID ) ] = ( x ) )
#define portINCREMENT_CRITICAL_NESTING_COUNT( xCoreID ) ( uxCriticalNestings[ ( xCoreID ) ]++ )
#define portDECREMENT_CRITICAL_NESTING_COUNT( xCoreID ) ( uxCriticalNestings[ ( xCoreID ) ]-- )

/*-----------------------------------------------------------*/

Expand Down
142 changes: 81 additions & 61 deletions tasks.c
Original file line number Diff line number Diff line change
Expand Up @@ -317,10 +317,10 @@
#define taskATTRIBUTE_IS_IDLE ( UBaseType_t ) ( 1U << 0U )

#if ( ( configNUMBER_OF_CORES > 1 ) && ( portCRITICAL_NESTING_IN_TCB == 1 ) )
#define portGET_CRITICAL_NESTING_COUNT() ( pxCurrentTCBs[ portGET_CORE_ID() ]->uxCriticalNesting )
#define portSET_CRITICAL_NESTING_COUNT( x ) ( pxCurrentTCBs[ portGET_CORE_ID() ]->uxCriticalNesting = ( x ) )
#define portINCREMENT_CRITICAL_NESTING_COUNT() ( pxCurrentTCBs[ portGET_CORE_ID() ]->uxCriticalNesting++ )
#define portDECREMENT_CRITICAL_NESTING_COUNT() ( pxCurrentTCBs[ portGET_CORE_ID() ]->uxCriticalNesting-- )
#define portGET_CRITICAL_NESTING_COUNT( xCoreID ) ( pxCurrentTCBs[ ( xCoreID ) ]->uxCriticalNesting )
#define portSET_CRITICAL_NESTING_COUNT( xCoreID, x ) ( pxCurrentTCBs[ ( xCoreID ) ]->uxCriticalNesting = ( x ) )
#define portINCREMENT_CRITICAL_NESTING_COUNT( xCoreID ) ( pxCurrentTCBs[ ( xCoreID ) ]->uxCriticalNesting++ )
#define portDECREMENT_CRITICAL_NESTING_COUNT( xCoreID ) ( pxCurrentTCBs[ ( xCoreID ) ]->uxCriticalNesting-- )
#endif /* #if ( ( configNUMBER_OF_CORES > 1 ) && ( portCRITICAL_NESTING_IN_TCB == 1 ) ) */

#define taskBITS_PER_BYTE ( ( size_t ) 8 )
Expand Down Expand Up @@ -807,13 +807,14 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
{
UBaseType_t uxPrevCriticalNesting;
const TCB_t * pxThisTCB;
BaseType_t xCoreID = ( BaseType_t ) portGET_CORE_ID();

/* This must only be called from within a task. */
portASSERT_IF_IN_ISR();

/* This function is always called with interrupts disabled
* so this is safe. */
pxThisTCB = pxCurrentTCBs[ portGET_CORE_ID() ];
pxThisTCB = pxCurrentTCBs[ xCoreID ];

while( pxThisTCB->xTaskRunState == taskTASK_SCHEDULED_TO_YIELD )
{
Expand All @@ -825,11 +826,11 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
* the suspension and critical nesting counts, as well as release
* and reacquire the correct locks. And then, do it all over again
* if our state changed again during the reacquisition. */
uxPrevCriticalNesting = portGET_CRITICAL_NESTING_COUNT();
uxPrevCriticalNesting = portGET_CRITICAL_NESTING_COUNT( xCoreID );

if( uxPrevCriticalNesting > 0U )
{
portSET_CRITICAL_NESTING_COUNT( 0U );
portSET_CRITICAL_NESTING_COUNT( xCoreID, 0U );
portRELEASE_ISR_LOCK();
}
else
Expand All @@ -854,8 +855,9 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
portDISABLE_INTERRUPTS();
portGET_TASK_LOCK();
portGET_ISR_LOCK();
xCoreID = ( BaseType_t ) portGET_CORE_ID();

portSET_CRITICAL_NESTING_COUNT( uxPrevCriticalNesting );
portSET_CRITICAL_NESTING_COUNT( xCoreID, uxPrevCriticalNesting );
chinglee-iot marked this conversation as resolved.
Show resolved Hide resolved

if( uxPrevCriticalNesting == 0U )
{
Expand All @@ -874,13 +876,14 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
BaseType_t xCurrentCoreTaskPriority;
BaseType_t xLowestPriorityCore = ( BaseType_t ) -1;
BaseType_t xCoreID;
const BaseType_t xCurrentCoreID = portGET_CORE_ID();

#if ( configRUN_MULTIPLE_PRIORITIES == 0 )
BaseType_t xYieldCount = 0;
#endif /* #if ( configRUN_MULTIPLE_PRIORITIES == 0 ) */

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

Expand Down Expand Up @@ -969,11 +972,11 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;

#if ( configRUN_MULTIPLE_PRIORITIES == 0 )
/* Verify that the calling core always yields to higher priority tasks. */
if( ( ( pxCurrentTCBs[ portGET_CORE_ID() ]->uxTaskAttributes & taskATTRIBUTE_IS_IDLE ) == 0U ) &&
( pxTCB->uxPriority > pxCurrentTCBs[ portGET_CORE_ID() ]->uxPriority ) )
if( ( ( pxCurrentTCBs[ xCurrentCoreID ]->uxTaskAttributes & taskATTRIBUTE_IS_IDLE ) == 0U ) &&
( pxTCB->uxPriority > pxCurrentTCBs[ xCurrentCoreID ]->uxPriority ) )
{
configASSERT( ( xYieldPendings[ portGET_CORE_ID() ] == pdTRUE ) ||
( taskTASK_IS_RUNNING( pxCurrentTCBs[ portGET_CORE_ID() ] ) == pdFALSE ) );
configASSERT( ( xYieldPendings[ xCurrentCoreID ] == pdTRUE ) ||
( taskTASK_IS_RUNNING( pxCurrentTCBs[ xCurrentCoreID ] ) == pdFALSE ) );
}
#endif
}
Expand Down Expand Up @@ -3880,7 +3883,7 @@ void vTaskSuspendAll( void )
ulState = portSET_INTERRUPT_MASK();

/* 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
* do not otherwise exhibit real time behaviour. */
Expand Down Expand Up @@ -4003,8 +4006,7 @@ BaseType_t xTaskResumeAll( void )
* tasks from this list into their appropriate ready list. */
taskENTER_CRITICAL();
{
BaseType_t xCoreID;
xCoreID = ( BaseType_t ) portGET_CORE_ID();
const BaseType_t xCoreID = ( BaseType_t ) portGET_CORE_ID();

/* If uxSchedulerSuspended is zero then this function does not match a
* previous call to vTaskSuspendAll(). */
Expand Down Expand Up @@ -5187,7 +5189,7 @@ BaseType_t xTaskIncrementTick( void )
/* vTaskSwitchContext() must never be called from within a critical section.
* This is not necessarily true for single core FreeRTOS, but it is for this
* SMP port. */
configASSERT( portGET_CRITICAL_NESTING_COUNT() == 0 );
configASSERT( portGET_CRITICAL_NESTING_COUNT( xCoreID ) == 0 );

if( uxSchedulerSuspended != ( UBaseType_t ) 0U )
{
Expand Down Expand Up @@ -6937,16 +6939,24 @@ static void prvResetNextTaskUnblockTime( void )
*/
void vTaskYieldWithinAPI( void )
{
UBaseType_t ulState;

traceENTER_vTaskYieldWithinAPI();

if( portGET_CRITICAL_NESTING_COUNT() == 0U )
{
portYIELD();
}
else
ulState = portSET_INTERRUPT_MASK();
{
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();
}
Expand Down Expand Up @@ -6995,40 +7005,43 @@ static void prvResetNextTaskUnblockTime( void )
traceENTER_vTaskEnterCritical();

portDISABLE_INTERRUPTS();

if( xSchedulerRunning != pdFALSE )
{
if( portGET_CRITICAL_NESTING_COUNT() == 0U )
{
portGET_TASK_LOCK();
portGET_ISR_LOCK();
}

portINCREMENT_CRITICAL_NESTING_COUNT();
const BaseType_t xCoreID = ( BaseType_t ) portGET_CORE_ID();

/* 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() == 1U )
if( xSchedulerRunning != pdFALSE )
{
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
* before a context switch and vTaskExitCritical() is called
* after pxCurrentTCB changes. Therefore this should not be
* used within vTaskSwitchContext(). */
prvCheckForRunStateChange();
portASSERT_IF_IN_ISR();

if( uxSchedulerSuspended == 0U )
{
/* 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
{
mtCOVERAGE_TEST_MARKER();
else
{
mtCOVERAGE_TEST_MARKER();
}
}

traceRETURN_vTaskEnterCritical();
Expand All @@ -7043,19 +7056,20 @@ static void prvResetNextTaskUnblockTime( void )
UBaseType_t vTaskEnterCriticalFromISR( void )
{
UBaseType_t uxSavedInterruptStatus = 0;
const BaseType_t xCoreID = ( BaseType_t ) portGET_CORE_ID();

traceENTER_vTaskEnterCriticalFromISR();

if( xSchedulerRunning != pdFALSE )
{
uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();

if( portGET_CRITICAL_NESTING_COUNT() == 0U )
if( portGET_CRITICAL_NESTING_COUNT( xCoreID ) == 0U )
{
portGET_ISR_LOCK();
}

portINCREMENT_CRITICAL_NESTING_COUNT();
portINCREMENT_CRITICAL_NESTING_COUNT( xCoreID );
}
else
{
Expand Down Expand Up @@ -7119,28 +7133,30 @@ static void prvResetNextTaskUnblockTime( void )

void vTaskExitCritical( void )
{
const BaseType_t xCoreID = ( BaseType_t ) portGET_CORE_ID();

traceENTER_vTaskExitCritical();

if( xSchedulerRunning != pdFALSE )
{
/* If critical nesting count is zero then this function
* 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
* to exit critical section from 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;

/* Get the xYieldPending stats inside the critical section. */
xYieldCurrentTask = xYieldPendings[ portGET_CORE_ID() ];
xYieldCurrentTask = xYieldPendings[ xCoreID ];

portRELEASE_ISR_LOCK();
portRELEASE_TASK_LOCK();
Expand Down Expand Up @@ -7180,19 +7196,23 @@ static void prvResetNextTaskUnblockTime( void )

void vTaskExitCriticalFromISR( UBaseType_t uxSavedInterruptStatus )
{
BaseType_t xCoreID;

traceENTER_vTaskExitCriticalFromISR( uxSavedInterruptStatus );

if( xSchedulerRunning != pdFALSE )
{
xCoreID = ( BaseType_t ) portGET_CORE_ID();

/* If critical nesting count is zero then this function
* 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();
portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
Expand Down
Loading