Assert if prvCheckForRunStateChange is called in ISR (#779)

* Assert if prvCheckForRunStateChange is called in ISR
pull/770/head^2
chinglee-iot 1 year ago committed by GitHub
parent 288d143357
commit 53229b1537
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -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();
}
}
}

Loading…
Cancel
Save