feat(freertos/smp): Allow vTaskPreemptionEnable() to be nested

Changed xPreemptionDisable to be a count rather than a pdTRUE/pdFALSE. This
allows nested calls to vTaskPreemptionEnable(), where a yield only occurs when
xPreemptionDisable is 0.

Co-authored-by: Sudeep Mohanty <sudeep.mohanty@espressif.com>
This commit is contained in:
Darian Leung 2024-06-16 00:37:28 +08:00 committed by Sudeep Mohanty
parent a6d6d1220f
commit ad7e48a7d5
2 changed files with 10 additions and 9 deletions

View file

@ -3179,7 +3179,7 @@ typedef struct xSTATIC_TCB
#endif #endif
uint8_t ucDummy7[ configMAX_TASK_NAME_LEN ]; uint8_t ucDummy7[ configMAX_TASK_NAME_LEN ];
#if ( configUSE_TASK_PREEMPTION_DISABLE == 1 ) #if ( configUSE_TASK_PREEMPTION_DISABLE == 1 )
BaseType_t xDummy25; UBaseType_t xDummy25;
#endif #endif
#if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) ) #if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) )
void * pxDummy8; void * pxDummy8;

17
tasks.c
View file

@ -394,7 +394,7 @@ typedef struct tskTaskControlBlock /* The old naming convention is used to
char pcTaskName[ configMAX_TASK_NAME_LEN ]; /**< Descriptive name given to the task when created. Facilitates debugging only. */ char pcTaskName[ configMAX_TASK_NAME_LEN ]; /**< Descriptive name given to the task when created. Facilitates debugging only. */
#if ( configUSE_TASK_PREEMPTION_DISABLE == 1 ) #if ( configUSE_TASK_PREEMPTION_DISABLE == 1 )
BaseType_t xPreemptionDisable; /**< Used to prevent the task from being preempted. */ UBaseType_t xPreemptionDisable; /**< Used to prevent the task from being preempted. */
#endif #endif
#if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) ) #if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) )
@ -941,7 +941,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
#endif #endif
{ {
#if ( configUSE_TASK_PREEMPTION_DISABLE == 1 ) #if ( configUSE_TASK_PREEMPTION_DISABLE == 1 )
if( pxCurrentTCBs[ xCoreID ]->xPreemptionDisable == pdFALSE ) if( pxCurrentTCBs[ xCoreID ]->xPreemptionDisable == 0U )
#endif #endif
{ {
xLowestPriorityToPreempt = xCurrentCoreTaskPriority; xLowestPriorityToPreempt = xCurrentCoreTaskPriority;
@ -1247,7 +1247,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
( xYieldPendings[ uxCore ] == pdFALSE ) ) ( xYieldPendings[ uxCore ] == pdFALSE ) )
{ {
#if ( configUSE_TASK_PREEMPTION_DISABLE == 1 ) #if ( configUSE_TASK_PREEMPTION_DISABLE == 1 )
if( pxCurrentTCBs[ uxCore ]->xPreemptionDisable == pdFALSE ) if( pxCurrentTCBs[ uxCore ]->xPreemptionDisable == 0U )
#endif #endif
{ {
xLowestPriority = xTaskPriority; xLowestPriority = xTaskPriority;
@ -2880,7 +2880,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode,
* there may now be another task of higher priority that * there may now be another task of higher priority that
* is ready to execute. */ * is ready to execute. */
#if ( configUSE_TASK_PREEMPTION_DISABLE == 1 ) #if ( configUSE_TASK_PREEMPTION_DISABLE == 1 )
if( pxTCB->xPreemptionDisable == pdFALSE ) if( pxTCB->xPreemptionDisable == 0U )
#endif #endif
{ {
xYieldRequired = pdTRUE; xYieldRequired = pdTRUE;
@ -3101,7 +3101,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode,
pxTCB = prvGetTCBFromHandle( xTask ); pxTCB = prvGetTCBFromHandle( xTask );
configASSERT( pxTCB != NULL ); configASSERT( pxTCB != NULL );
pxTCB->xPreemptionDisable = pdTRUE; pxTCB->xPreemptionDisable++;
} }
taskEXIT_CRITICAL(); taskEXIT_CRITICAL();
@ -3124,12 +3124,13 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode,
{ {
pxTCB = prvGetTCBFromHandle( xTask ); pxTCB = prvGetTCBFromHandle( xTask );
configASSERT( pxTCB != NULL ); configASSERT( pxTCB != NULL );
configASSERT( pxTCB->xPreemptionDisable > 0U );
pxTCB->xPreemptionDisable = pdFALSE; pxTCB->xPreemptionDisable--;
if( xSchedulerRunning != pdFALSE ) if( xSchedulerRunning != pdFALSE )
{ {
if( taskTASK_IS_RUNNING( pxTCB ) == pdTRUE ) if( ( pxTCB->xPreemptionDisable == 0U ) && ( taskTASK_IS_RUNNING( pxTCB ) == pdTRUE ) )
{ {
xCoreID = ( BaseType_t ) pxTCB->xTaskRunState; xCoreID = ( BaseType_t ) pxTCB->xTaskRunState;
prvYieldCore( xCoreID ); prvYieldCore( xCoreID );
@ -4928,7 +4929,7 @@ BaseType_t xTaskIncrementTick( void )
for( xCoreID = 0; xCoreID < ( BaseType_t ) configNUMBER_OF_CORES; xCoreID++ ) for( xCoreID = 0; xCoreID < ( BaseType_t ) configNUMBER_OF_CORES; xCoreID++ )
{ {
#if ( configUSE_TASK_PREEMPTION_DISABLE == 1 ) #if ( configUSE_TASK_PREEMPTION_DISABLE == 1 )
if( pxCurrentTCBs[ xCoreID ]->xPreemptionDisable == pdFALSE ) if( pxCurrentTCBs[ xCoreID ]->xPreemptionDisable == 0U )
#endif #endif
{ {
if( xYieldPendings[ xCoreID ] != pdFALSE ) if( xYieldPendings[ xCoreID ] != pdFALSE )