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 /** POSIX wrapper for THREADX */ 17 /** */ 18 /** */ 19 /** */ 20 /**************************************************************************/ 21 /**************************************************************************/ 22 23 /* Include necessary system files. */ 24 25 #include "tx_api.h" /* Threadx API */ 26 #include "pthread.h" /* Posix API */ 27 #include "px_int.h" /* Posix helper functions */ 28 #include "tx_thread.h" /* Internal ThreadX thread management. */ 29 30 /**************************************************************************/ 31 /* */ 32 /* FUNCTION RELEASE */ 33 /* */ 34 /* internal_signal_dispatch PORTABLE C */ 35 /* 6.1.7 */ 36 /* AUTHOR */ 37 /* */ 38 /* William E. Lamie, Microsoft Corporation */ 39 /* */ 40 /* DESCRIPTION */ 41 /* */ 42 /* Signal handler thread. */ 43 /* */ 44 /* INPUT */ 45 /* */ 46 /* id Signal */ 47 /* */ 48 /* OUTPUT */ 49 /* */ 50 /* none */ 51 /* */ 52 /* CALLS */ 53 /* */ 54 /* posix_internal_error Generic error Handler */ 55 /* tx_thread_identify */ 56 /* tx_event_flags_set */ 57 /* tx_thread_resume */ 58 /* posix_destroy_pthread */ 59 /* tx_thread_suspend */ 60 /* */ 61 /* CALLED BY */ 62 /* */ 63 /* Internal Code */ 64 /* */ 65 /* RELEASE HISTORY */ 66 /* */ 67 /* DATE NAME DESCRIPTION */ 68 /* */ 69 /* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ 70 /* */ 71 /**************************************************************************/ internal_signal_dispatch(ULONG id)72void internal_signal_dispatch(ULONG id) 73 { 74 75 TX_INTERRUPT_SAVE_AREA 76 77 POSIX_TCB *signal_thread; 78 POSIX_TCB *target_thread; 79 VOID (*handler)(int); 80 81 82 /* Determine if the desired signal is valid. */ 83 if (id > SIGRTMAX) 84 { 85 86 /* System error! */ 87 posix_internal_error(444); 88 return; 89 } 90 91 /* Pickup signal thread. */ 92 signal_thread = (POSIX_TCB *) tx_thread_identify(); 93 94 /* Is it non-NULL? */ 95 if (!signal_thread) 96 { 97 98 /* System error! */ 99 posix_internal_error(444); 100 return; 101 } 102 103 /* Pickup target thread. */ 104 target_thread = signal_thread -> signals.base_thread_ptr; 105 106 /* Pickup signal handler function pointer. */ 107 handler = target_thread -> signals.signal_func[id]; 108 109 /* See if there is a signal handler setup for this signal. */ 110 if (handler) 111 { 112 113 /* Yes, there is a signal handler - call it! */ 114 (handler)((int) id); 115 } 116 117 /* Set the event flag corresponding the signal. */ 118 tx_event_flags_set(&(target_thread -> signals.signal_event_flags), (((ULONG) 1) << id), TX_OR); 119 120 /* Ensure the flag is left in a clear state. */ 121 tx_event_flags_set(&(target_thread -> signals.signal_event_flags), ~(((ULONG) 1) << id), TX_AND); 122 123 /* Now we need to clear this signal and terminate this signal handler thread. */ 124 125 /* Disable interrupts. */ 126 TX_DISABLE 127 128 /* Clear this signal from the pending list. */ 129 target_thread -> signals.signal_pending.signal_set = target_thread -> signals.signal_pending.signal_set & ~(((unsigned long) 1) << id); 130 131 /* Decrement the signal nesting count. */ 132 target_thread -> signals.signal_nesting_depth--; 133 134 /* Is this the last nested signal leaving? */ 135 if (target_thread -> signals.signal_nesting_depth == 0) 136 { 137 138 /* Clear the top signal thread link and resume the target thread. */ 139 target_thread -> signals.top_signal_thread = NULL; 140 141 /* Restore interrupts. */ 142 TX_RESTORE 143 144 /* Resume the target thread. */ 145 tx_thread_resume((TX_THREAD *) target_thread); 146 } 147 else 148 { 149 150 /* Otherwise, there are more signal threads still active. */ 151 152 /* Setup the new top signal thread pointer. */ 153 target_thread -> signals.top_signal_thread = signal_thread -> signals.next_signal_thread; 154 155 /* Restore interrupts. */ 156 TX_RESTORE 157 158 /* Resume the signal handler thread. */ 159 tx_thread_resume((TX_THREAD *) signal_thread -> signals.next_signal_thread); 160 } 161 162 /* Now we need to mark this signal thread for destruction. */ 163 posix_destroy_pthread(signal_thread,(VOID *) 0); 164 165 /* Self-suspend the current signal thread. */ 166 tx_thread_suspend((TX_THREAD *) signal_thread); 167 } 168