From ad7e48a7d5219542f2d30951e0ef7b961073b046 Mon Sep 17 00:00:00 2001 From: Darian Leung Date: Sun, 16 Jun 2024 00:37:28 +0800 Subject: [PATCH] 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 --- include/FreeRTOS.h | 2 +- tasks.c | 17 +++++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/include/FreeRTOS.h b/include/FreeRTOS.h index ce8530e7d..c16c098bb 100644 --- a/include/FreeRTOS.h +++ b/include/FreeRTOS.h @@ -3179,7 +3179,7 @@ typedef struct xSTATIC_TCB #endif uint8_t ucDummy7[ configMAX_TASK_NAME_LEN ]; #if ( configUSE_TASK_PREEMPTION_DISABLE == 1 ) - BaseType_t xDummy25; + UBaseType_t xDummy25; #endif #if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) ) void * pxDummy8; diff --git a/tasks.c b/tasks.c index 4a975f55e..2256d2885 100644 --- a/tasks.c +++ b/tasks.c @@ -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. */ #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 #if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) ) @@ -941,7 +941,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; #endif { #if ( configUSE_TASK_PREEMPTION_DISABLE == 1 ) - if( pxCurrentTCBs[ xCoreID ]->xPreemptionDisable == pdFALSE ) + if( pxCurrentTCBs[ xCoreID ]->xPreemptionDisable == 0U ) #endif { xLowestPriorityToPreempt = xCurrentCoreTaskPriority; @@ -1247,7 +1247,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; ( xYieldPendings[ uxCore ] == pdFALSE ) ) { #if ( configUSE_TASK_PREEMPTION_DISABLE == 1 ) - if( pxCurrentTCBs[ uxCore ]->xPreemptionDisable == pdFALSE ) + if( pxCurrentTCBs[ uxCore ]->xPreemptionDisable == 0U ) #endif { xLowestPriority = xTaskPriority; @@ -2880,7 +2880,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, * there may now be another task of higher priority that * is ready to execute. */ #if ( configUSE_TASK_PREEMPTION_DISABLE == 1 ) - if( pxTCB->xPreemptionDisable == pdFALSE ) + if( pxTCB->xPreemptionDisable == 0U ) #endif { xYieldRequired = pdTRUE; @@ -3101,7 +3101,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, pxTCB = prvGetTCBFromHandle( xTask ); configASSERT( pxTCB != NULL ); - pxTCB->xPreemptionDisable = pdTRUE; + pxTCB->xPreemptionDisable++; } taskEXIT_CRITICAL(); @@ -3124,12 +3124,13 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, { pxTCB = prvGetTCBFromHandle( xTask ); configASSERT( pxTCB != NULL ); + configASSERT( pxTCB->xPreemptionDisable > 0U ); - pxTCB->xPreemptionDisable = pdFALSE; + pxTCB->xPreemptionDisable--; if( xSchedulerRunning != pdFALSE ) { - if( taskTASK_IS_RUNNING( pxTCB ) == pdTRUE ) + if( ( pxTCB->xPreemptionDisable == 0U ) && ( taskTASK_IS_RUNNING( pxTCB ) == pdTRUE ) ) { xCoreID = ( BaseType_t ) pxTCB->xTaskRunState; prvYieldCore( xCoreID ); @@ -4928,7 +4929,7 @@ BaseType_t xTaskIncrementTick( void ) for( xCoreID = 0; xCoreID < ( BaseType_t ) configNUMBER_OF_CORES; xCoreID++ ) { #if ( configUSE_TASK_PREEMPTION_DISABLE == 1 ) - if( pxCurrentTCBs[ xCoreID ]->xPreemptionDisable == pdFALSE ) + if( pxCurrentTCBs[ xCoreID ]->xPreemptionDisable == 0U ) #endif { if( xYieldPendings[ xCoreID ] != pdFALSE )