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