Skip to content

Update unpaired critical section in vTaskDelete for readability #958

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 36 additions & 37 deletions tasks.c
Original file line number Diff line number Diff line change
Expand Up @@ -2190,6 +2190,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode,
void vTaskDelete( TaskHandle_t xTaskToDelete )
{
TCB_t * pxTCB;
BaseType_t xDeleteTCBInIdleTask = pdFALSE;

traceENTER_vTaskDelete( xTaskToDelete );

Expand Down Expand Up @@ -2247,6 +2248,9 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode,
* portPRE_TASK_DELETE_HOOK() does not return in the Win32 port. */
traceTASK_DELETE( pxTCB );

/* Delete the task TCB in idle task. */
xDeleteTCBInIdleTask = pdTRUE;

/* The pre-delete hook is primarily for the Windows simulator,
* in which Windows specific clean up operations are performed,
* after which it is not possible to yield away from this task -
Expand All @@ -2268,61 +2272,56 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode,
prvResetNextTaskUnblockTime();
}
}
taskEXIT_CRITICAL();

#if ( configNUMBER_OF_CORES == 1 )
/* If the task is not deleting itself, call prvDeleteTCB from outside of
* critical section. If a task deletes itself, prvDeleteTCB is called
* from prvCheckTasksWaitingTermination which is called from Idle task. */
if( xDeleteTCBInIdleTask != pdTRUE )
{
taskEXIT_CRITICAL();

/* If the task is not deleting itself, call prvDeleteTCB from outside of
* critical section. If a task deletes itself, prvDeleteTCB is called
* from prvCheckTasksWaitingTermination which is called from Idle task. */
if( pxTCB != pxCurrentTCB )
{
prvDeleteTCB( pxTCB );
}
prvDeleteTCB( pxTCB );
}

/* Force a reschedule if it is the currently running task that has just
* been deleted. */
if( xSchedulerRunning != pdFALSE )
/* Force a reschedule if it is the currently running task that has just
* been deleted. */
if( xSchedulerRunning != pdFALSE )
{
#if ( configNUMBER_OF_CORES == 1 )
{
if( pxTCB == pxCurrentTCB )
{
configASSERT( uxSchedulerSuspended == 0 );
portYIELD_WITHIN_API();
taskYIELD_WITHIN_API();
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
}
#else /* #if ( configNUMBER_OF_CORES == 1 ) */
{
/* If a running task is not deleting itself, call prvDeleteTCB. If a running
* task deletes itself, prvDeleteTCB is called from prvCheckTasksWaitingTermination
* which is called from Idle task. */
if( pxTCB->xTaskRunState == taskTASK_NOT_RUNNING )
{
prvDeleteTCB( pxTCB );
}

/* Force a reschedule if the task that has just been deleted was running. */
if( ( xSchedulerRunning != pdFALSE ) && ( taskTASK_IS_RUNNING( pxTCB ) == pdTRUE ) )
#else /* #if ( configNUMBER_OF_CORES == 1 ) */
{
if( pxTCB->xTaskRunState == ( BaseType_t ) portGET_CORE_ID() )
{
configASSERT( uxSchedulerSuspended == 0 );
vTaskYieldWithinAPI();
}
else
/* It is important to use critical section here because
* checking run state of a task must be done inside a
* critical section. */
taskENTER_CRITICAL();
{
prvYieldCore( pxTCB->xTaskRunState );
if( taskTASK_IS_RUNNING( pxTCB ) == pdTRUE )
{
if( pxTCB->xTaskRunState == ( BaseType_t ) portGET_CORE_ID() )
{
configASSERT( uxSchedulerSuspended == 0 );
taskYIELD_WITHIN_API();
}
else
{
prvYieldCore( pxTCB->xTaskRunState );
}
}
}
taskEXIT_CRITICAL();
}

taskEXIT_CRITICAL();
#endif /* #if ( configNUMBER_OF_CORES == 1 ) */
}
#endif /* #if ( configNUMBER_OF_CORES == 1 ) */

traceRETURN_vTaskDelete();
}
Expand Down