1 /**************************************************************************/ 2 /* */ 3 /* Copyright (c) Microsoft Corporation. All rights reserved. */ 4 /* */ 5 /* This software is licensed under the Microsoft Software License */ 6 /* Terms for Microsoft Azure RTOS. Full text of the license can be */ 7 /* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ 8 /* and in the root directory of this software. */ 9 /* */ 10 /**************************************************************************/ 11 12 13 /**************************************************************************/ 14 /**************************************************************************/ 15 /** */ 16 /** ThreadX Component */ 17 /** */ 18 /** Thread */ 19 /** */ 20 /**************************************************************************/ 21 /**************************************************************************/ 22 23 #define TX_SOURCE_CODE 24 #define TX_THREAD_SMP_SOURCE_CODE 25 26 27 /* Include necessary system files. */ 28 29 #include "tx_api.h" 30 #include "tx_thread.h" 31 32 33 /**************************************************************************/ 34 /* */ 35 /* FUNCTION RELEASE */ 36 /* */ 37 /* _tx_thread_system_preempt_check PORTABLE SMP */ 38 /* 6.1 */ 39 /* AUTHOR */ 40 /* */ 41 /* William E. Lamie, Microsoft Corporation */ 42 /* */ 43 /* DESCRIPTION */ 44 /* */ 45 /* This function checks for preemption that could have occurred as a */ 46 /* result scheduling activities occurring while the preempt disable */ 47 /* flag was set. */ 48 /* */ 49 /* INPUT */ 50 /* */ 51 /* None */ 52 /* */ 53 /* OUTPUT */ 54 /* */ 55 /* None */ 56 /* */ 57 /* CALLS */ 58 /* */ 59 /* _tx_thread_system_return Return to the system */ 60 /* */ 61 /* CALLED BY */ 62 /* */ 63 /* Other ThreadX Components */ 64 /* */ 65 /* RELEASE HISTORY */ 66 /* */ 67 /* DATE NAME DESCRIPTION */ 68 /* */ 69 /* 09-30-2020 William E. Lamie Initial Version 6.1 */ 70 /* */ 71 /**************************************************************************/ _tx_thread_system_preempt_check(VOID)72VOID _tx_thread_system_preempt_check(VOID) 73 { 74 75 TX_INTERRUPT_SAVE_AREA 76 77 UINT core_index; 78 UINT restore_needed; 79 80 81 /* Disable interrupts. */ 82 TX_DISABLE 83 84 /* Set the restore needed flag. */ 85 restore_needed = TX_TRUE; 86 87 /* Pickup the index. */ 88 core_index = TX_SMP_CORE_ID; 89 90 /* Determine if the call is from initialization, an ISR or if the preempt disable flag is set. */ 91 if (_tx_thread_system_state[core_index] == ((ULONG) 0)) 92 { 93 94 /* Ensure the preempt disable flag is not set. */ 95 if (_tx_thread_preempt_disable == ((UINT) 0)) 96 { 97 98 /* Thread execution - now determine if preemption should take place. */ 99 if (_tx_thread_current_ptr[core_index] != _tx_thread_execute_ptr[core_index]) 100 { 101 102 /* Yes, thread preemption should take place. */ 103 104 #ifdef TX_ENABLE_STACK_CHECKING 105 TX_THREAD *thread_ptr; 106 107 /* Pickup the next execute pointer. */ 108 thread_ptr = _tx_thread_execute_ptr[core_index]; 109 110 /* Determine if there is a thread pointer. */ 111 if (thread_ptr != TX_NULL) 112 { 113 114 /* Check this thread's stack. */ 115 TX_THREAD_STACK_CHECK(thread_ptr) 116 } 117 #endif 118 119 #ifdef TX_THREAD_ENABLE_PERFORMANCE_INFO 120 121 /* Determine if an idle system return is present. */ 122 if (_tx_thread_execute_ptr[core_index] == TX_NULL) 123 { 124 125 /* Yes, increment the return to idle return count. */ 126 _tx_thread_performance_idle_return_count++; 127 } 128 else 129 { 130 131 /* No, there is another thread ready to run and will be scheduled upon return. */ 132 _tx_thread_performance_non_idle_return_count++; 133 } 134 #endif 135 136 #ifndef TX_NOT_INTERRUPTABLE 137 138 /* Increment the preempt disable flag in order to keep the protection. */ 139 _tx_thread_preempt_disable++; 140 141 /* Restore interrupts. */ 142 TX_RESTORE 143 #endif 144 145 /* Return to the system so the higher priority thread can be scheduled. */ 146 _tx_thread_system_return(); 147 148 #ifdef TX_NOT_INTERRUPTABLE 149 150 /* Restore interrupts. */ 151 TX_RESTORE 152 #endif 153 154 /* Clear the restore needed flag, since the interrupt poster/protection has been done. */ 155 restore_needed = TX_FALSE; 156 } 157 } 158 } 159 160 /* Determine if the protection still needs to be restored. */ 161 if (restore_needed == TX_TRUE) 162 { 163 164 /* Restore interrupts. */ 165 TX_RESTORE 166 } 167 } 168 169