diff --git a/tasks.c b/tasks.c index 49a5fa1df..80ad29497 100644 --- a/tasks.c +++ b/tasks.c @@ -461,7 +461,7 @@ typedef struct tskTaskControlBlock /* The old naming convention is used to #endif #if ( configUSE_TASK_PREEMPTION_DISABLE == 1 ) - BaseType_t xDeferredStateChange; /**< Used to indicate if the task's state change is deferred. */ + UBaseType_t uxDeferredStateChange; /**< Used to indicate if the task's state change is deferred. */ #endif #if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) ) @@ -2309,7 +2309,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, * task enables preemption. The deletion will be performed in vTaskPreemptionEnable(). */ if( pxTCB->uxPreemptionDisable > 0U ) { - pxTCB->xDeferredStateChange |= tskDEFERRED_DELETION; + pxTCB->uxDeferredStateChange |= tskDEFERRED_DELETION; xDeferredDeletion = pdTRUE; } else @@ -3243,13 +3243,13 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, { /* Process deferred state changes which were inflicted while * preemption was disabled. */ - if( pxTCB->xDeferredStateChange != 0U ) + if( pxTCB->uxDeferredStateChange != 0U ) { - if( pxTCB->xDeferredStateChange & tskDEFERRED_DELETION ) + if( pxTCB->uxDeferredStateChange & tskDEFERRED_DELETION ) { vTaskDelete( xTask ); } - else if( pxTCB->xDeferredStateChange & tskDEFERRED_SUSPENSION ) + else if( pxTCB->uxDeferredStateChange & tskDEFERRED_SUSPENSION ) { vTaskSuspend( xTask ); } @@ -3258,7 +3258,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, mtCOVERAGE_TEST_MARKER(); } - pxTCB->xDeferredStateChange = 0U; + pxTCB->uxDeferredStateChange = 0U; } else { @@ -3315,7 +3315,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, * task enables preemption. The suspension will be performed in vTaskPreemptionEnable(). */ if( pxTCB->uxPreemptionDisable > 0U ) { - pxTCB->xDeferredStateChange |= tskDEFERRED_SUSPENSION; + pxTCB->uxDeferredStateChange |= tskDEFERRED_SUSPENSION; xDeferredSuspension = pdTRUE; } else @@ -3558,6 +3558,10 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, { TCB_t * const pxTCB = xTaskToResume; + #if ( configUSE_TASK_PREEMPTION_DISABLE == 1 ) + BaseType_t xTaskResumed = pdFALSE; + #endif /* #if ( configUSE_TASK_PREEMPTION_DISABLE == 1 ) */ + traceENTER_vTaskResume( xTaskToResume ); /* It does not make sense to resume the calling task. */ @@ -3580,23 +3584,43 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, { kernelENTER_CRITICAL(); { - if( prvTaskIsTaskSuspended( pxTCB ) != pdFALSE ) - { - traceTASK_RESUME( pxTCB ); + #if ( configUSE_TASK_PREEMPTION_DISABLE == 1 ) - /* The ready list can be accessed even if the scheduler is - * suspended because this is inside a critical section. */ - ( void ) uxListRemove( &( pxTCB->xStateListItem ) ); - prvAddTaskToReadyList( pxTCB ); + /* If the task being resumed is in a deferred suspension state, + * we simply clear the deferred suspension state and return. */ + if( pxTCB->uxDeferredStateChange & tskDEFERRED_SUSPENSION ) + { + pxTCB->uxDeferredStateChange &= ~tskDEFERRED_SUSPENSION; + xTaskResumed = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + #endif /* configUSE_TASK_PREEMPTION_DISABLE */ - /* This yield may not cause the task just resumed to run, - * but will leave the lists in the correct state for the - * next yield. */ - taskYIELD_ANY_CORE_IF_USING_PREEMPTION( pxTCB ); - } - else + #if ( configUSE_TASK_PREEMPTION_DISABLE == 1 ) + if( xTaskResumed == pdFALSE ) + #endif /* #if ( configUSE_TASK_PREEMPTION_DISABLE == 1 ) */ { - mtCOVERAGE_TEST_MARKER(); + if( prvTaskIsTaskSuspended( pxTCB ) != pdFALSE ) + { + traceTASK_RESUME( pxTCB ); + + /* The ready list can be accessed even if the scheduler is + * suspended because this is inside a critical section. */ + ( void ) uxListRemove( &( pxTCB->xStateListItem ) ); + prvAddTaskToReadyList( pxTCB ); + + /* This yield may not cause the task just resumed to run, + * but will leave the lists in the correct state for the + * next yield. */ + taskYIELD_ANY_CORE_IF_USING_PREEMPTION( pxTCB ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } } } kernelEXIT_CRITICAL();