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>
diff --git a/portable/ThirdParty/GCC/RP2040/include/portmacro.h b/portable/ThirdParty/GCC/RP2040/include/portmacro.h
index 14f5894..ed9dbad 100644
--- a/portable/ThirdParty/GCC/RP2040/include/portmacro.h
+++ b/portable/ThirdParty/GCC/RP2040/include/portmacro.h
@@ -158,10 +158,10 @@
#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 ) ]-- )
/*-----------------------------------------------------------*/
diff --git a/tasks.c b/tasks.c
index 22e11f0..7d9c875 100644
--- a/tasks.c
+++ b/tasks.c
@@ -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 )
@@ -807,13 +807,14 @@
{
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 )
{
@@ -825,11 +826,11 @@
* 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
@@ -854,8 +855,9 @@
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 );
if( uxPrevCriticalNesting == 0U )
{
@@ -874,13 +876,14 @@
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 )
@@ -969,11 +972,11 @@
#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
}
@@ -3880,7 +3883,7 @@
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. */
@@ -4003,8 +4006,7 @@
* 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(). */
@@ -5187,7 +5189,7 @@
/* 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 )
{
@@ -6937,16 +6939,24 @@
*/
void vTaskYieldWithinAPI( void )
{
+ UBaseType_t ulState;
+
traceENTER_vTaskYieldWithinAPI();
- if( portGET_CRITICAL_NESTING_COUNT() == 0U )
+ ulState = portSET_INTERRUPT_MASK();
{
- portYIELD();
+ const BaseType_t xCoreID = ( BaseType_t ) portGET_CORE_ID();
+
+ if( portGET_CRITICAL_NESTING_COUNT( xCoreID ) == 0U )
+ {
+ portYIELD();
+ }
+ else
+ {
+ xYieldPendings[ xCoreID ] = pdTRUE;
+ }
}
- else
- {
- xYieldPendings[ portGET_CORE_ID() ] = pdTRUE;
- }
+ portCLEAR_INTERRUPT_MASK( ulState );
traceRETURN_vTaskYieldWithinAPI();
}
@@ -6995,40 +7005,43 @@
traceENTER_vTaskEnterCritical();
portDISABLE_INTERRUPTS();
-
- if( xSchedulerRunning != pdFALSE )
{
- if( portGET_CRITICAL_NESTING_COUNT() == 0U )
+ const BaseType_t xCoreID = ( BaseType_t ) portGET_CORE_ID();
+
+ if( xSchedulerRunning != pdFALSE )
{
- portGET_TASK_LOCK();
- portGET_ISR_LOCK();
- }
-
- portINCREMENT_CRITICAL_NESTING_COUNT();
-
- /* 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 )
- {
- portASSERT_IF_IN_ISR();
-
- if( uxSchedulerSuspended == 0U )
+ if( portGET_CRITICAL_NESTING_COUNT( xCoreID ) == 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();
+ portGET_TASK_LOCK();
+ portGET_ISR_LOCK();
+ }
+
+ 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 )
+ {
+ 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();
@@ -7043,6 +7056,7 @@
UBaseType_t vTaskEnterCriticalFromISR( void )
{
UBaseType_t uxSavedInterruptStatus = 0;
+ const BaseType_t xCoreID = ( BaseType_t ) portGET_CORE_ID();
traceENTER_vTaskEnterCriticalFromISR();
@@ -7050,12 +7064,12 @@
{
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
{
@@ -7119,28 +7133,30 @@
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();
@@ -7180,19 +7196,23 @@
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 );