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 /* Define small routines used for the TX_DISABLE/TX_RESTORE macros. */ 33 _tx_thread_interrupt_disable(void)34UINT _tx_thread_interrupt_disable(void) 35 { 36 37 UINT previous_value; 38 39 40 previous_value = _tx_thread_interrupt_control(TX_INT_DISABLE); 41 return(previous_value); 42 } 43 44 _tx_thread_interrupt_restore(UINT previous_posture)45VOID _tx_thread_interrupt_restore(UINT previous_posture) 46 { 47 48 previous_posture = _tx_thread_interrupt_control(previous_posture); 49 } 50 51 52 /**************************************************************************/ 53 /* */ 54 /* FUNCTION RELEASE */ 55 /* */ 56 /* _tx_thread_interrupt_control SMP/Linux/GCC */ 57 /* 6.1 */ 58 /* AUTHOR */ 59 /* */ 60 /* William E. Lamie, Microsoft Corporation */ 61 /* */ 62 /* DESCRIPTION */ 63 /* */ 64 /* This function is responsible for changing the interrupt lockout */ 65 /* posture of the system. */ 66 /* */ 67 /* INPUT */ 68 /* */ 69 /* new_posture New interrupt lockout posture */ 70 /* */ 71 /* OUTPUT */ 72 /* */ 73 /* old_posture Old interrupt lockout posture */ 74 /* */ 75 /* CALLS */ 76 /* */ 77 /* _tx_linux_mutex_obtain */ 78 /* pthread_self */ 79 /* pthread_getschedparam */ 80 /* _tx_linux_mutex_release_all */ 81 /* pthread_exit */ 82 /* */ 83 /* CALLED BY */ 84 /* */ 85 /* Application Code */ 86 /* */ 87 /* RELEASE HISTORY */ 88 /* */ 89 /* DATE NAME DESCRIPTION */ 90 /* */ 91 /* 09-30-2020 William E. Lamie Initial Version 6.1 */ 92 /* */ 93 /**************************************************************************/ _tx_thread_interrupt_control(UINT new_posture)94UINT _tx_thread_interrupt_control(UINT new_posture) 95 { 96 97 UINT old_posture; 98 TX_THREAD *thread_ptr; 99 pthread_t thread_id; 100 int exit_code = 0; 101 UINT core; 102 103 104 /* Lock Linux mutex. */ 105 _tx_linux_mutex_obtain(&_tx_linux_mutex); 106 107 #ifdef TX_LINUX_DEBUG_ENABLE 108 109 /* Determine if this is a disable or enable request. */ 110 if (new_posture == TX_INT_ENABLE) 111 { 112 113 /* Enable. */ 114 _tx_linux_debug_entry_insert("RESTORE", __FILE__, __LINE__); 115 } 116 else 117 { 118 119 /* Disable. */ 120 _tx_linux_debug_entry_insert("DISABLE", __FILE__, __LINE__); 121 } 122 #endif 123 124 /* Pickup the id of the current thread. */ 125 thread_id = pthread_self(); 126 127 /* Get the currently running virtual core. */ 128 core = _tx_thread_smp_core_get(); 129 130 /* Pickup the current thread pointer. */ 131 thread_ptr = _tx_thread_current_ptr[core]; 132 133 /* Determine if this is a thread and it does not 134 match the current thread pointer. */ 135 if ((_tx_linux_threadx_thread) && 136 ((!thread_ptr) || (!pthread_equal(thread_ptr -> tx_thread_linux_thread_id, thread_id)))) 137 { 138 139 /* This indicates the Linux thread was actually terminated by ThreadX is only 140 being allowed to run in order to cleanup its resources. */ 141 /* Unlock linux mutex. */ 142 _tx_linux_mutex_release_all(&_tx_linux_mutex); 143 pthread_exit((void *)&exit_code); 144 } 145 146 /* Determine the current interrupt lockout condition. */ 147 if (_tx_linux_mutex.tx_linux_mutex_nested_count == 1) 148 { 149 150 /* Interrupts are enabled. */ 151 old_posture = TX_INT_ENABLE; 152 } 153 else 154 { 155 156 /* Interrupts are disabled. */ 157 old_posture = TX_INT_DISABLE; 158 } 159 160 /* First, determine if this call is from a non-thread. */ 161 if (_tx_thread_system_state[core]) 162 { 163 164 /* Determine how to apply the new posture. */ 165 if (new_posture == TX_INT_ENABLE) 166 { 167 168 /* Clear the disabled flag. */ 169 _tx_linux_global_int_disabled_flag = TX_FALSE; 170 171 /* Determine if the critical section is locked. */ 172 _tx_linux_mutex_release_all(&_tx_linux_mutex); 173 } 174 else if (new_posture == TX_INT_DISABLE) 175 { 176 177 /* Set the disabled flag. */ 178 _tx_linux_global_int_disabled_flag = TX_TRUE; 179 } 180 } 181 else if (thread_ptr) 182 { 183 184 /* Determine how to apply the new posture. */ 185 if (new_posture == TX_INT_ENABLE) 186 { 187 188 /* Clear the disabled flag. */ 189 thread_ptr -> tx_thread_linux_int_disabled_flag = TX_FALSE; 190 191 /* Determine if the critical section is locked. */ 192 _tx_linux_mutex_release_all(&_tx_linux_mutex); 193 } 194 else if (new_posture == TX_INT_DISABLE) 195 { 196 197 /* Set the disabled flag. */ 198 thread_ptr -> tx_thread_linux_int_disabled_flag = TX_TRUE; 199 } 200 } 201 202 /* Return the previous interrupt disable posture. */ 203 return(old_posture); 204 } 205 206