From e98d4569d22967e23b1354b863e0ecfac2bf8f19 Mon Sep 17 00:00:00 2001 From: Ching-Hsin Lee Date: Tue, 5 Sep 2023 17:20:49 +0800 Subject: [PATCH 1/2] Remove portCHECK_IF_IN_ISR macro in kernel * Remove portCHECK_IF_IN_ISR macro in kernel * Assert if prvCheckForRunStateChange is called in ISR --- include/FreeRTOS.h | 8 ---- tasks.c | 94 ++++++++++++++++++++++------------------------ 2 files changed, 45 insertions(+), 57 deletions(-) diff --git a/include/FreeRTOS.h b/include/FreeRTOS.h index ca5818eae4..5aaf3068dd 100644 --- a/include/FreeRTOS.h +++ b/include/FreeRTOS.h @@ -448,14 +448,6 @@ #endif /* portGET_ISR_LOCK */ -#ifndef portCHECK_IF_IN_ISR - - #if ( configNUMBER_OF_CORES > 1 ) - #error portCHECK_IF_IN_ISR is required in SMP - #endif - -#endif /* portCHECK_IF_IN_ISR */ - #ifndef portENTER_CRITICAL_FROM_ISR #if ( configNUMBER_OF_CORES > 1 ) diff --git a/tasks.c b/tasks.c index 6cb233e7a5..b655d12540 100644 --- a/tasks.c +++ b/tasks.c @@ -693,62 +693,58 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; UBaseType_t uxPrevCriticalNesting; const TCB_t * pxThisTCB; - /* This should be skipped if called from an ISR. If the task on the current - * core is no longer running, then vTaskSwitchContext() probably should - * be run before returning, but we don't have a way to force that to happen - * from here. */ - if( portCHECK_IF_IN_ISR() == pdFALSE ) - { - /* This function is always called with interrupts disabled - * so this is safe. */ - pxThisTCB = pxCurrentTCBs[ portGET_CORE_ID() ]; - - while( pxThisTCB->xTaskRunState == taskTASK_YIELDING ) - { - /* We are only here if we just entered a critical section - * or if we just suspended the scheduler, and another task - * has requested that we yield. - * - * This is slightly complicated since we need to save and restore - * 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(); - - if( uxPrevCriticalNesting > 0U ) - { - portSET_CRITICAL_NESTING_COUNT( 0U ); - portRELEASE_ISR_LOCK(); - } - else - { - /* The scheduler is suspended. uxSchedulerSuspended is updated - * only when the task is not requested to yield. */ - mtCOVERAGE_TEST_MARKER(); - } + /* This must only be called from within a task. */ + portASSERT_IF_IN_ISR(); - portRELEASE_TASK_LOCK(); + /* This function is always called with interrupts disabled + * so this is safe. */ + pxThisTCB = pxCurrentTCBs[ portGET_CORE_ID() ]; - portMEMORY_BARRIER(); - configASSERT( pxThisTCB->xTaskRunState == taskTASK_YIELDING ); + while( pxThisTCB->xTaskRunState == taskTASK_YIELDING ) + { + /* We are only here if we just entered a critical section + * or if we just suspended the scheduler, and another task + * has requested that we yield. + * + * This is slightly complicated since we need to save and restore + * 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(); - portENABLE_INTERRUPTS(); + if( uxPrevCriticalNesting > 0U ) + { + portSET_CRITICAL_NESTING_COUNT( 0U ); + portRELEASE_ISR_LOCK(); + } + else + { + /* The scheduler is suspended. uxSchedulerSuspended is updated + * only when the task is not requested to yield. */ + mtCOVERAGE_TEST_MARKER(); + } - /* Enabling interrupts should cause this core to immediately - * service the pending interrupt and yield. If the run state is still - * yielding here then that is a problem. */ - configASSERT( pxThisTCB->xTaskRunState != taskTASK_YIELDING ); + portRELEASE_TASK_LOCK(); - portDISABLE_INTERRUPTS(); - portGET_TASK_LOCK(); - portGET_ISR_LOCK(); + portMEMORY_BARRIER(); + configASSERT( pxThisTCB->xTaskRunState == taskTASK_YIELDING ); - portSET_CRITICAL_NESTING_COUNT( uxPrevCriticalNesting ); + portENABLE_INTERRUPTS(); - if( uxPrevCriticalNesting == 0U ) - { - portRELEASE_ISR_LOCK(); - } + /* Enabling interrupts should cause this core to immediately + * service the pending interrupt and yield. If the run state is still + * yielding here then that is a problem. */ + configASSERT( pxThisTCB->xTaskRunState != taskTASK_YIELDING ); + + portDISABLE_INTERRUPTS(); + portGET_TASK_LOCK(); + portGET_ISR_LOCK(); + + portSET_CRITICAL_NESTING_COUNT( uxPrevCriticalNesting ); + + if( uxPrevCriticalNesting == 0U ) + { + portRELEASE_ISR_LOCK(); } } } From a81520d3514deea71ddb1ad3fbbf33da6b4f0127 Mon Sep 17 00:00:00 2001 From: Ching-Hsin Lee Date: Tue, 5 Sep 2023 17:46:31 +0800 Subject: [PATCH 2/2] Added back portCHECK_IF_IN_ISR() --- include/FreeRTOS.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/FreeRTOS.h b/include/FreeRTOS.h index 5aaf3068dd..ca5818eae4 100644 --- a/include/FreeRTOS.h +++ b/include/FreeRTOS.h @@ -448,6 +448,14 @@ #endif /* portGET_ISR_LOCK */ +#ifndef portCHECK_IF_IN_ISR + + #if ( configNUMBER_OF_CORES > 1 ) + #error portCHECK_IF_IN_ISR is required in SMP + #endif + +#endif /* portCHECK_IF_IN_ISR */ + #ifndef portENTER_CRITICAL_FROM_ISR #if ( configNUMBER_OF_CORES > 1 )