| 612 | /*-----------------------------------------------------------*/ |
| 613 | |
| 614 | static 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 ); |
no outgoing calls
no test coverage detected