Assert if prvCheckForRunStateChange is called in ISR (#779)
* Assert if prvCheckForRunStateChange is called in ISR
diff --git a/tasks.c b/tasks.c
index a0651b1..7eaef88 100644
--- a/tasks.c
+++ b/tasks.c
@@ -693,62 +693,58 @@
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 must only be called from within a task. */
+ portASSERT_IF_IN_ISR();
+
+ /* This function is always called with interrupts disabled
+ * so this is safe. */
+ pxThisTCB = pxCurrentTCBs[ portGET_CORE_ID() ];
+
+ while( pxThisTCB->xTaskRunState == taskTASK_YIELDING )
{
- /* This function is always called with interrupts disabled
- * so this is safe. */
- pxThisTCB = pxCurrentTCBs[ portGET_CORE_ID() ];
+ /* 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();
- while( pxThisTCB->xTaskRunState == taskTASK_YIELDING )
+ if( uxPrevCriticalNesting > 0U )
{
- /* 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();
+ 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();
+ }
- 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();
- }
+ portRELEASE_TASK_LOCK();
- portRELEASE_TASK_LOCK();
+ portMEMORY_BARRIER();
+ configASSERT( pxThisTCB->xTaskRunState == taskTASK_YIELDING );
- portMEMORY_BARRIER();
- configASSERT( pxThisTCB->xTaskRunState == taskTASK_YIELDING );
+ portENABLE_INTERRUPTS();
- portENABLE_INTERRUPTS();
+ /* 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 );
- /* 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();
- portDISABLE_INTERRUPTS();
- portGET_TASK_LOCK();
- portGET_ISR_LOCK();
+ portSET_CRITICAL_NESTING_COUNT( uxPrevCriticalNesting );
- portSET_CRITICAL_NESTING_COUNT( uxPrevCriticalNesting );
-
- if( uxPrevCriticalNesting == 0U )
- {
- portRELEASE_ISR_LOCK();
- }
+ if( uxPrevCriticalNesting == 0U )
+ {
+ portRELEASE_ISR_LOCK();
}
}
}