From a8260c9c77216416ea842b8f1110ef2c1293104c Mon Sep 17 00:00:00 2001 From: Mahavir Jain Date: Thu, 25 Nov 2021 17:28:09 +0530 Subject: [PATCH] freertos: fix thread safety for checking scheduler state This issue was earlier fixed in commit 79e74e5d5f948e585bec586db7f482a2f2df50dc but during migration to newer FreeRTOS release, it got introduced again. This commit fixes thread safety issues with configASSERT() calls regarding the value of uxSchedulerSuspended. A false negative occurs if a context switch to the opposite core occurs in between the getting the core ID and the assesment. Relevant https://github.com/espressif/esp-idf/issues/4230 Closes https://github.com/espressif/esp-idf/issues/7726 Closes IDFGH-6041 --- components/freertos/tasks.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/components/freertos/tasks.c b/components/freertos/tasks.c index dd0487958c..23c38521e6 100644 --- a/components/freertos/tasks.c +++ b/components/freertos/tasks.c @@ -1421,7 +1421,7 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB, TaskFunction_t pxTaskCode configASSERT( pxPreviousWakeTime ); configASSERT( ( xTimeIncrement > 0U ) ); - configASSERT( uxSchedulerSuspended[xPortGetCoreID()] == 0 ); + configASSERT( xTaskGetSchedulerState() != taskSCHEDULER_SUSPENDED ); taskENTER_CRITICAL( &xTaskQueueMutex ); { @@ -1505,7 +1505,7 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB, TaskFunction_t pxTaskCode /* A delay time of zero just forces a reschedule. */ if( xTicksToDelay > ( TickType_t ) 0U ) { - configASSERT( uxSchedulerSuspended[xPortGetCoreID()] == 0 ); + configASSERT( xTaskGetSchedulerState() != taskSCHEDULER_SUSPENDED ); taskENTER_CRITICAL( &xTaskQueueMutex ); { traceTASK_DELAY(); @@ -2434,9 +2434,9 @@ TCB_t *pxTCB = NULL; BaseType_t xAlreadyYielded = pdFALSE; TickType_t xTicksToNextUnblockTime; - /* If uxSchedulerSuspended[xPortGetCoreID()] is zero then this function does not match a + /* If scheduler state is `taskSCHEDULER_RUNNING` then this function does not match a previous call to taskENTER_CRITICAL( &xTaskQueueMutex ). */ - configASSERT( uxSchedulerSuspended[xPortGetCoreID()] ); + configASSERT( xTaskGetSchedulerState() != taskSCHEDULER_RUNNING ); /* It is possible that an ISR caused a task to be removed from an event list while the scheduler was suspended. If this was the case then the @@ -2874,7 +2874,7 @@ BaseType_t xYieldRequired = pdFALSE; /* Must not be called with the scheduler suspended as the implementation relies on xPendedTicks being wound down to 0 in xTaskResumeAll(). */ - configASSERT( uxSchedulerSuspended[xPortGetCoreID()] == 0 ); + configASSERT( xTaskGetSchedulerState() != taskSCHEDULER_SUSPENDED ); /* Use xPendedTicks to mimic xTicksToCatchUp number of ticks occuring when the scheduler is suspended so the ticks are executed in xTaskResumeAll(). */ @@ -4511,7 +4511,9 @@ TCB_t *pxTCB; BaseType_t xTaskGetSchedulerState( void ) { BaseType_t xReturn; + unsigned state; + state = portENTER_CRITICAL_NESTED(); if( xSchedulerRunning == pdFALSE ) { xReturn = taskSCHEDULER_NOT_STARTED; @@ -4527,6 +4529,7 @@ TCB_t *pxTCB; xReturn = taskSCHEDULER_SUSPENDED; } } + portEXIT_CRITICAL_NESTED(state); return xReturn; }