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
25
26 /* Include necessary system files. */
27
28 #include "tx_api.h"
29 #include "tx_trace.h"
30 #include "tx_thread.h"
31
32
33 /**************************************************************************/
34 /* */
35 /* FUNCTION RELEASE */
36 /* */
37 /* _tx_thread_wait_abort PORTABLE C */
38 /* 6.2.1 */
39 /* AUTHOR */
40 /* */
41 /* William E. Lamie, Microsoft Corporation */
42 /* */
43 /* DESCRIPTION */
44 /* */
45 /* This function aborts the wait condition that the specified thread */
46 /* is in - regardless of what object the thread is waiting on - and */
47 /* returns a TX_WAIT_ABORTED status to the specified thread. */
48 /* */
49 /* INPUT */
50 /* */
51 /* thread_ptr Thread to abort the wait on */
52 /* */
53 /* OUTPUT */
54 /* */
55 /* status Return completion status */
56 /* */
57 /* CALLS */
58 /* */
59 /* Suspension Cleanup Functions */
60 /* _tx_thread_system_resume */
61 /* _tx_thread_system_ni_resume Non-interruptable resume thread */
62 /* */
63 /* CALLED BY */
64 /* */
65 /* Application code */
66 /* */
67 /* RELEASE HISTORY */
68 /* */
69 /* DATE NAME DESCRIPTION */
70 /* */
71 /* 05-19-2020 William E. Lamie Initial Version 6.0 */
72 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
73 /* resulting in version 6.1 */
74 /* 03-08-2023 Scott Larson Check if thread is coming out */
75 /* of suspension elsewhere, */
76 /* resulting in version 6.2.1 */
77 /* */
78 /**************************************************************************/
_tx_thread_wait_abort(TX_THREAD * thread_ptr)79 UINT _tx_thread_wait_abort(TX_THREAD *thread_ptr)
80 {
81
82 TX_INTERRUPT_SAVE_AREA
83
84 VOID (*suspend_cleanup)(struct TX_THREAD_STRUCT *suspend_thread_ptr, ULONG suspension_sequence);
85 UINT status;
86 ULONG suspension_sequence;
87
88
89 /* Disable interrupts. */
90 TX_DISABLE
91
92 /* If trace is enabled, insert this event into the trace buffer. */
93 TX_TRACE_IN_LINE_INSERT(TX_TRACE_THREAD_WAIT_ABORT, thread_ptr, thread_ptr -> tx_thread_state, 0, 0, TX_TRACE_THREAD_EVENTS)
94
95 /* Log this kernel call. */
96 TX_EL_THREAD_WAIT_ABORT_INSERT
97
98 /* Determine if the thread is currently suspended. */
99 if (thread_ptr -> tx_thread_state < TX_SLEEP)
100 {
101
102 /* Thread is either ready, completed, terminated, or in a pure
103 suspension condition. */
104
105 /* Restore interrupts. */
106 TX_RESTORE
107
108 /* Just return with an error message to indicate that
109 nothing was done. */
110 status = TX_WAIT_ABORT_ERROR;
111 }
112 else
113 {
114
115 /* Check for a sleep condition. */
116 if (thread_ptr -> tx_thread_state == TX_SLEEP)
117 {
118
119 /* Set the state to terminated. */
120 thread_ptr -> tx_thread_state = TX_SUSPENDED;
121
122 /* Set the TX_WAIT_ABORTED status in the thread that is
123 sleeping. */
124 thread_ptr -> tx_thread_suspend_status = TX_WAIT_ABORTED;
125
126 /* Make sure there isn't a suspend cleanup routine. */
127 thread_ptr -> tx_thread_suspend_cleanup = TX_NULL;
128
129 #ifndef TX_NOT_INTERRUPTABLE
130
131 /* Increment the disable preemption flag. */
132 _tx_thread_preempt_disable++;
133
134 /* Restore interrupts. */
135 TX_RESTORE
136 #endif
137 }
138 else if(thread_ptr -> tx_thread_suspend_cleanup == TX_NULL)
139 {
140 /* Thread is coming out of suspension elsewhere. */
141
142 #ifndef TX_NOT_INTERRUPTABLE
143 /* Increment the disable preemption flag. */
144 _tx_thread_preempt_disable++;
145
146 /* Restore interrupts. */
147 TX_RESTORE
148 #endif
149 }
150 else
151 {
152
153 /* Process all other suspension timeouts. */
154
155 /* Set the state to suspended. */
156 thread_ptr -> tx_thread_state = TX_SUSPENDED;
157
158 /* Pickup the cleanup routine address. */
159 suspend_cleanup = thread_ptr -> tx_thread_suspend_cleanup;
160
161 #ifndef TX_NOT_INTERRUPTABLE
162
163 /* Pickup the suspension sequence number that is used later to verify that the
164 cleanup is still necessary. */
165 suspension_sequence = thread_ptr -> tx_thread_suspension_sequence;
166 #else
167
168 /* When not interruptable is selected, the suspension sequence is not used - just set to 0. */
169 suspension_sequence = ((ULONG) 0);
170 #endif
171
172 /* Set the TX_WAIT_ABORTED status in the thread that was
173 suspended. */
174 thread_ptr -> tx_thread_suspend_status = TX_WAIT_ABORTED;
175
176 #ifndef TX_NOT_INTERRUPTABLE
177
178 /* Increment the disable preemption flag. */
179 _tx_thread_preempt_disable++;
180
181 /* Restore interrupts. */
182 TX_RESTORE
183 #endif
184
185 /* Call cleanup routine. */
186 (suspend_cleanup)(thread_ptr, suspension_sequence);
187 }
188
189 /* If the abort of the thread wait was successful, if so resume the thread. */
190 if (thread_ptr -> tx_thread_suspend_status == TX_WAIT_ABORTED)
191 {
192
193 #ifdef TX_THREAD_ENABLE_PERFORMANCE_INFO
194
195 /* Increment the total number of thread wait aborts. */
196 _tx_thread_performance_wait_abort_count++;
197
198 /* Increment this thread's wait abort count. */
199 thread_ptr -> tx_thread_performance_wait_abort_count++;
200 #endif
201
202 #ifdef TX_NOT_INTERRUPTABLE
203
204 /* Resume the thread! */
205 _tx_thread_system_ni_resume(thread_ptr);
206
207 /* Restore interrupts. */
208 TX_RESTORE
209 #else
210
211 /* Lift the suspension on the previously waiting thread. */
212 _tx_thread_system_resume(thread_ptr);
213 #endif
214
215 /* Return a successful status. */
216 status = TX_SUCCESS;
217 }
218 else
219 {
220
221 #ifdef TX_NOT_INTERRUPTABLE
222
223 /* Restore interrupts. */
224 TX_RESTORE
225
226 #else
227
228 /* Disable interrupts. */
229 TX_DISABLE
230
231 /* Decrement the disable preemption flag. */
232 _tx_thread_preempt_disable--;
233
234 /* Restore interrupts. */
235 TX_RESTORE
236 #endif
237
238 /* Return with an error message to indicate that
239 nothing was done. */
240 status = TX_WAIT_ABORT_ERROR;
241 }
242 }
243
244 /* Return completion status. */
245 return(status);
246 }
247
248