|
|
|
@ -693,62 +693,58 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
|
|
|
|
|
UBaseType_t uxPrevCriticalNesting;
|
|
|
|
|
const TCB_t * pxThisTCB;
|
|
|
|
|
|
|
|
|
|
/* This should be skipped if called from an ISR. If the task on the current
|
|
|
|
|
* core is no longer running, then vTaskSwitchContext() probably should
|
|
|
|
|
* be run before returning, but we don't have a way to force that to happen
|
|
|
|
|
* from here. */
|
|
|
|
|
if( portCHECK_IF_IN_ISR() == pdFALSE )
|
|
|
|
|
{
|
|
|
|
|
/* This function is always called with interrupts disabled
|
|
|
|
|
* so this is safe. */
|
|
|
|
|
pxThisTCB = pxCurrentTCBs[ portGET_CORE_ID() ];
|
|
|
|
|
|
|
|
|
|
while( pxThisTCB->xTaskRunState == taskTASK_YIELDING )
|
|
|
|
|
{
|
|
|
|
|
/* We are only here if we just entered a critical section
|
|
|
|
|
* or if we just suspended the scheduler, and another task
|
|
|
|
|
* has requested that we yield.
|
|
|
|
|
*
|
|
|
|
|
* This is slightly complicated since we need to save and restore
|
|
|
|
|
* the suspension and critical nesting counts, as well as release
|
|
|
|
|
* and reacquire the correct locks. And then, do it all over again
|
|
|
|
|
* if our state changed again during the reacquisition. */
|
|
|
|
|
uxPrevCriticalNesting = portGET_CRITICAL_NESTING_COUNT();
|
|
|
|
|
|
|
|
|
|
if( uxPrevCriticalNesting > 0U )
|
|
|
|
|
{
|
|
|
|
|
portSET_CRITICAL_NESTING_COUNT( 0U );
|
|
|
|
|
portRELEASE_ISR_LOCK();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* The scheduler is suspended. uxSchedulerSuspended is updated
|
|
|
|
|
* only when the task is not requested to yield. */
|
|
|
|
|
mtCOVERAGE_TEST_MARKER();
|
|
|
|
|
}
|
|
|
|
|
/* This must only be called from within a task. */
|
|
|
|
|
portASSERT_IF_IN_ISR();
|
|
|
|
|
|
|
|
|
|
portRELEASE_TASK_LOCK();
|
|
|
|
|
/* This function is always called with interrupts disabled
|
|
|
|
|
* so this is safe. */
|
|
|
|
|
pxThisTCB = pxCurrentTCBs[ portGET_CORE_ID() ];
|
|
|
|
|
|
|
|
|
|
portMEMORY_BARRIER();
|
|
|
|
|
configASSERT( pxThisTCB->xTaskRunState == taskTASK_YIELDING );
|
|
|
|
|
while( pxThisTCB->xTaskRunState == taskTASK_YIELDING )
|
|
|
|
|
{
|
|
|
|
|
/* We are only here if we just entered a critical section
|
|
|
|
|
* or if we just suspended the scheduler, and another task
|
|
|
|
|
* has requested that we yield.
|
|
|
|
|
*
|
|
|
|
|
* This is slightly complicated since we need to save and restore
|
|
|
|
|
* the suspension and critical nesting counts, as well as release
|
|
|
|
|
* and reacquire the correct locks. And then, do it all over again
|
|
|
|
|
* if our state changed again during the reacquisition. */
|
|
|
|
|
uxPrevCriticalNesting = portGET_CRITICAL_NESTING_COUNT();
|
|
|
|
|
|
|
|
|
|
portENABLE_INTERRUPTS();
|
|
|
|
|
if( uxPrevCriticalNesting > 0U )
|
|
|
|
|
{
|
|
|
|
|
portSET_CRITICAL_NESTING_COUNT( 0U );
|
|
|
|
|
portRELEASE_ISR_LOCK();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* The scheduler is suspended. uxSchedulerSuspended is updated
|
|
|
|
|
* only when the task is not requested to yield. */
|
|
|
|
|
mtCOVERAGE_TEST_MARKER();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Enabling interrupts should cause this core to immediately
|
|
|
|
|
* service the pending interrupt and yield. If the run state is still
|
|
|
|
|
* yielding here then that is a problem. */
|
|
|
|
|
configASSERT( pxThisTCB->xTaskRunState != taskTASK_YIELDING );
|
|
|
|
|
portRELEASE_TASK_LOCK();
|
|
|
|
|
|
|
|
|
|
portDISABLE_INTERRUPTS();
|
|
|
|
|
portGET_TASK_LOCK();
|
|
|
|
|
portGET_ISR_LOCK();
|
|
|
|
|
portMEMORY_BARRIER();
|
|
|
|
|
configASSERT( pxThisTCB->xTaskRunState == taskTASK_YIELDING );
|
|
|
|
|
|
|
|
|
|
portSET_CRITICAL_NESTING_COUNT( uxPrevCriticalNesting );
|
|
|
|
|
portENABLE_INTERRUPTS();
|
|
|
|
|
|
|
|
|
|
if( uxPrevCriticalNesting == 0U )
|
|
|
|
|
{
|
|
|
|
|
portRELEASE_ISR_LOCK();
|
|
|
|
|
}
|
|
|
|
|
/* Enabling interrupts should cause this core to immediately
|
|
|
|
|
* service the pending interrupt and yield. If the run state is still
|
|
|
|
|
* yielding here then that is a problem. */
|
|
|
|
|
configASSERT( pxThisTCB->xTaskRunState != taskTASK_YIELDING );
|
|
|
|
|
|
|
|
|
|
portDISABLE_INTERRUPTS();
|
|
|
|
|
portGET_TASK_LOCK();
|
|
|
|
|
portGET_ISR_LOCK();
|
|
|
|
|
|
|
|
|
|
portSET_CRITICAL_NESTING_COUNT( uxPrevCriticalNesting );
|
|
|
|
|
|
|
|
|
|
if( uxPrevCriticalNesting == 0U )
|
|
|
|
|
{
|
|
|
|
|
portRELEASE_ISR_LOCK();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|