MCPcopy Create free account
hub / github.com/FreeRTOS/FreeRTOS-Kernel / prvCheckForRunStateChange

Function prvCheckForRunStateChange

tasks.c:614–687  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

612/*-----------------------------------------------------------*/
613
614static void prvCheckForRunStateChange( void )
615{
616 UBaseType_t uxPrevCriticalNesting;
617 UBaseType_t uxPrevSchedulerSuspended;
618 TCB_t * pxThisTCB;
619
620 /* This should be skipped when entering a critical section within
621 * an ISR. If the task on the current core is no longer running, then
622 * vTaskSwitchContext() probably should be run before returning, but
623 * we don't have a way to force that to happen from here. */
624 if( portCHECK_IF_IN_ISR() == pdFALSE )
625 {
626 /* This function is always called with interrupts disabled
627 * so this is safe. */
628 pxThisTCB = pxCurrentTCBs[ portGET_CORE_ID() ];
629
630 while( pxThisTCB->xTaskRunState == taskTASK_YIELDING )
631 {
632 /* We are only here if we just entered a critical section
633 * or if we just suspended the scheduler, and another task
634 * has requested that we yield.
635 *
636 * This is slightly complicated since we need to save and restore
637 * the suspension and critical nesting counts, as well as release
638 * and reacquire the correct locks. And then do it all over again
639 * if our state changed again during the reacquisition. */
640
641 uxPrevCriticalNesting = pxThisTCB->uxCriticalNesting;
642 uxPrevSchedulerSuspended = uxSchedulerSuspended;
643
644 /* this must only be called the first time we enter into a critical
645 * section, otherwise it could context switch in the middle of a
646 * critical section. */
647 configASSERT( uxPrevCriticalNesting + uxPrevSchedulerSuspended == 1U );
648
649 uxSchedulerSuspended = 0U;
650
651 if( uxPrevCriticalNesting > 0U )
652 {
653 pxThisTCB->uxCriticalNesting = 0U;
654 portRELEASE_ISR_LOCK();
655 portRELEASE_TASK_LOCK();
656 }
657 else
658 {
659 /* uxPrevSchedulerSuspended must be 1 */
660 portRELEASE_TASK_LOCK();
661 }
662
663 portMEMORY_BARRIER();
664 configASSERT( pxThisTCB->xTaskRunState == taskTASK_YIELDING );
665
666 portENABLE_INTERRUPTS();
667
668 /* Enabling interrupts should cause this core to immediately
669 * service the pending interrupt and yield. If the run state is still
670 * yielding here then that is a problem. */
671 configASSERT( pxThisTCB->xTaskRunState != taskTASK_YIELDING );

Callers 2

vTaskSuspendAllFunction · 0.85
vTaskEnterCriticalFunction · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected