Skip to content

Commit 88674cb

Browse files
committed
Update the uxSchedulerSuspended after prvCheckForRunStateChange
* Update the uxSchedulerSuspended after the prvCheckForRunStateChange to prevent race condition in fromISR APIs
1 parent 161a2c7 commit 88674cb

File tree

1 file changed

+15
-20
lines changed

1 file changed

+15
-20
lines changed

tasks.c

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -671,7 +671,6 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
671671
static void prvCheckForRunStateChange( void )
672672
{
673673
UBaseType_t uxPrevCriticalNesting;
674-
UBaseType_t uxPrevSchedulerSuspended;
675674
TCB_t * pxThisTCB;
676675

677676
/* This should be skipped if called from an ISR. If the task on the current
@@ -695,24 +694,19 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
695694
* and reacquire the correct locks. And then, do it all over again
696695
* if our state changed again during the reacquisition. */
697696
uxPrevCriticalNesting = portGET_CRITICAL_NESTING_COUNT();
698-
uxPrevSchedulerSuspended = uxSchedulerSuspended;
699-
700-
/* This must only be called the first time we enter into a critical
701-
* section, otherwise it could context switch in the middle of a
702-
* critical section. */
703-
configASSERT( ( uxPrevCriticalNesting + uxPrevSchedulerSuspended ) == 1U );
704697

705698
if( uxPrevCriticalNesting > 0U )
706699
{
707700
portSET_CRITICAL_NESTING_COUNT( 0U );
701+
portRELEASE_ISR_LOCK();
708702
}
709703
else
710704
{
711-
portGET_ISR_LOCK();
712-
uxSchedulerSuspended = 0U;
705+
/* The scheduler is suspended. uxSchedulerSuspended is updated
706+
* only when the task is not requested to yield. */
707+
mtCOVERAGE_TEST_MARKER();
713708
}
714709

715-
portRELEASE_ISR_LOCK();
716710
portRELEASE_TASK_LOCK();
717711

718712
portMEMORY_BARRIER();
@@ -730,12 +724,9 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
730724
portGET_ISR_LOCK();
731725

732726
portSET_CRITICAL_NESTING_COUNT( uxPrevCriticalNesting );
733-
uxSchedulerSuspended = uxPrevSchedulerSuspended;
734727

735728
if( uxPrevCriticalNesting == 0U )
736729
{
737-
/* uxPrevSchedulerSuspended must be 1. */
738-
configASSERT( uxPrevSchedulerSuspended != ( UBaseType_t ) pdFALSE );
739730
portRELEASE_ISR_LOCK();
740731
}
741732
}
@@ -3351,14 +3342,11 @@ void vTaskSuspendAll( void )
33513342
portSOFTWARE_BARRIER();
33523343

33533344
portGET_TASK_LOCK();
3354-
portGET_ISR_LOCK();
3355-
3356-
/* The scheduler is suspended if uxSchedulerSuspended is non-zero. An increment
3357-
* is used to allow calls to vTaskSuspendAll() to nest. */
3358-
++uxSchedulerSuspended;
3359-
portRELEASE_ISR_LOCK();
33603345

3361-
if( uxSchedulerSuspended == 1U )
3346+
/* uxSchedulerSuspended is increased after prvCheckForRunStateChange. The
3347+
* purpose is to prevent altering the variable when fromISR APIs are readying
3348+
* it. */
3349+
if( uxSchedulerSuspended == 0U )
33623350
{
33633351
if( portGET_CRITICAL_NESTING_COUNT() == 0U )
33643352
{
@@ -3374,6 +3362,13 @@ void vTaskSuspendAll( void )
33743362
mtCOVERAGE_TEST_MARKER();
33753363
}
33763364

3365+
portGET_ISR_LOCK();
3366+
3367+
/* The scheduler is suspended if uxSchedulerSuspended is non-zero. An increment
3368+
* is used to allow calls to vTaskSuspendAll() to nest. */
3369+
++uxSchedulerSuspended;
3370+
portRELEASE_ISR_LOCK();
3371+
33773372
portCLEAR_INTERRUPT_MASK( ulState );
33783373
}
33793374
else

0 commit comments

Comments
 (0)