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_thread.h"
29 #ifdef TX_THREAD_ENABLE_PERFORMANCE_INFO
30 #include "tx_trace.h"
31 #endif
32
33
34 /**************************************************************************/
35 /* */
36 /* FUNCTION RELEASE */
37 /* */
38 /* _tx_thread_performance_info_get PORTABLE C */
39 /* 6.1 */
40 /* AUTHOR */
41 /* */
42 /* William E. Lamie, Microsoft Corporation */
43 /* */
44 /* DESCRIPTION */
45 /* */
46 /* This function retrieves performance information from the specified */
47 /* thread. */
48 /* */
49 /* INPUT */
50 /* */
51 /* thread_ptr Pointer to thread control block */
52 /* resumptions Destination for number of times */
53 /* thread was resumed */
54 /* suspensions Destination for number of times */
55 /* thread was suspended */
56 /* solicited_preemptions Destination for number of times */
57 /* thread called another service */
58 /* that resulted in preemption */
59 /* interrupt_preemptions Destination for number of times */
60 /* thread was preempted by another */
61 /* thread made ready in Interrupt */
62 /* Service Routine (ISR) */
63 /* priority_inversions Destination for number of times */
64 /* a priority inversion was */
65 /* detected for this thread */
66 /* time_slices Destination for number of times */
67 /* thread was time-sliced */
68 /* relinquishes Destination for number of thread */
69 /* relinquishes */
70 /* timeouts Destination for number of timeouts*/
71 /* for thread */
72 /* wait_aborts Destination for number of wait */
73 /* aborts for thread */
74 /* last_preempted_by Destination for pointer of the */
75 /* thread that last preempted this */
76 /* thread */
77 /* */
78 /* OUTPUT */
79 /* */
80 /* status Completion status */
81 /* */
82 /* CALLS */
83 /* */
84 /* None */
85 /* */
86 /* CALLED BY */
87 /* */
88 /* Application Code */
89 /* */
90 /* RELEASE HISTORY */
91 /* */
92 /* DATE NAME DESCRIPTION */
93 /* */
94 /* 05-19-2020 William E. Lamie Initial Version 6.0 */
95 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
96 /* resulting in version 6.1 */
97 /* */
98 /**************************************************************************/
_tx_thread_performance_info_get(TX_THREAD * thread_ptr,ULONG * resumptions,ULONG * suspensions,ULONG * solicited_preemptions,ULONG * interrupt_preemptions,ULONG * priority_inversions,ULONG * time_slices,ULONG * relinquishes,ULONG * timeouts,ULONG * wait_aborts,TX_THREAD ** last_preempted_by)99 UINT _tx_thread_performance_info_get(TX_THREAD *thread_ptr, ULONG *resumptions, ULONG *suspensions,
100 ULONG *solicited_preemptions, ULONG *interrupt_preemptions, ULONG *priority_inversions,
101 ULONG *time_slices, ULONG *relinquishes, ULONG *timeouts, ULONG *wait_aborts, TX_THREAD **last_preempted_by)
102 {
103
104 #ifdef TX_THREAD_ENABLE_PERFORMANCE_INFO
105
106 TX_INTERRUPT_SAVE_AREA
107 UINT status;
108
109
110 /* Determine if this is a legal request. */
111 if (thread_ptr == TX_NULL)
112 {
113
114 /* Thread pointer is illegal, return error. */
115 status = TX_PTR_ERROR;
116 }
117
118 /* Determine if the thread ID is invalid. */
119 else if (thread_ptr -> tx_thread_id != TX_THREAD_ID)
120 {
121
122 /* Thread pointer is illegal, return error. */
123 status = TX_PTR_ERROR;
124 }
125 else
126 {
127
128 /* Disable interrupts. */
129 TX_DISABLE
130
131 /* If trace is enabled, insert this event into the trace buffer. */
132 TX_TRACE_IN_LINE_INSERT(TX_TRACE_THREAD_PERFORMANCE_INFO_GET, thread_ptr, thread_ptr -> tx_thread_state, 0, 0, TX_TRACE_THREAD_EVENTS)
133
134 /* Log this kernel call. */
135 TX_EL_THREAD_PERFORMANCE_INFO_GET_INSERT
136
137 /* Retrieve all the pertinent information and return it in the supplied
138 destinations. */
139
140 /* Retrieve number of resumptions for this thread. */
141 if (resumptions != TX_NULL)
142 {
143
144 *resumptions = thread_ptr -> tx_thread_performance_resume_count;
145 }
146
147 /* Retrieve number of suspensions for this thread. */
148 if (suspensions != TX_NULL)
149 {
150
151 *suspensions = thread_ptr -> tx_thread_performance_suspend_count;
152 }
153
154 /* Retrieve number of solicited preemptions for this thread. */
155 if (solicited_preemptions != TX_NULL)
156 {
157
158 *solicited_preemptions = thread_ptr -> tx_thread_performance_solicited_preemption_count;
159 }
160
161 /* Retrieve number of interrupt preemptions for this thread. */
162 if (interrupt_preemptions != TX_NULL)
163 {
164
165 *interrupt_preemptions = thread_ptr -> tx_thread_performance_interrupt_preemption_count;
166 }
167
168 /* Retrieve number of priority inversions for this thread. */
169 if (priority_inversions != TX_NULL)
170 {
171
172 *priority_inversions = thread_ptr -> tx_thread_performance_priority_inversion_count;
173 }
174
175 /* Retrieve number of time-slices for this thread. */
176 if (time_slices != TX_NULL)
177 {
178
179 *time_slices = thread_ptr -> tx_thread_performance_time_slice_count;
180 }
181
182 /* Retrieve number of relinquishes for this thread. */
183 if (relinquishes != TX_NULL)
184 {
185
186 *relinquishes = thread_ptr -> tx_thread_performance_relinquish_count;
187 }
188
189 /* Retrieve number of timeouts for this thread. */
190 if (timeouts != TX_NULL)
191 {
192
193 *timeouts = thread_ptr -> tx_thread_performance_timeout_count;
194 }
195
196 /* Retrieve number of wait aborts for this thread. */
197 if (wait_aborts != TX_NULL)
198 {
199
200 *wait_aborts = thread_ptr -> tx_thread_performance_wait_abort_count;
201 }
202
203 /* Retrieve the pointer of the last thread that preempted this thread. */
204 if (last_preempted_by != TX_NULL)
205 {
206
207 *last_preempted_by = thread_ptr -> tx_thread_performance_last_preempting_thread;
208 }
209
210 /* Restore interrupts. */
211 TX_RESTORE
212
213 /* Return completion status. */
214 status = TX_SUCCESS;
215 }
216 #else
217 UINT status;
218
219
220 /* Access input arguments just for the sake of lint, MISRA, etc. */
221 if (thread_ptr != TX_NULL)
222 {
223
224 /* Not enabled, return error. */
225 status = TX_FEATURE_NOT_ENABLED;
226 }
227 else if (resumptions != TX_NULL)
228 {
229
230 /* Not enabled, return error. */
231 status = TX_FEATURE_NOT_ENABLED;
232 }
233 else if (suspensions != TX_NULL)
234 {
235
236 /* Not enabled, return error. */
237 status = TX_FEATURE_NOT_ENABLED;
238 }
239 else if (solicited_preemptions != TX_NULL)
240 {
241
242 /* Not enabled, return error. */
243 status = TX_FEATURE_NOT_ENABLED;
244 }
245 else if (interrupt_preemptions != TX_NULL)
246 {
247
248 /* Not enabled, return error. */
249 status = TX_FEATURE_NOT_ENABLED;
250 }
251 else if (priority_inversions != TX_NULL)
252 {
253
254 /* Not enabled, return error. */
255 status = TX_FEATURE_NOT_ENABLED;
256 }
257 else if (time_slices != TX_NULL)
258 {
259
260 /* Not enabled, return error. */
261 status = TX_FEATURE_NOT_ENABLED;
262 }
263 else if (relinquishes != TX_NULL)
264 {
265
266 /* Not enabled, return error. */
267 status = TX_FEATURE_NOT_ENABLED;
268 }
269 else if (timeouts != TX_NULL)
270 {
271
272 /* Not enabled, return error. */
273 status = TX_FEATURE_NOT_ENABLED;
274 }
275 else if (wait_aborts != TX_NULL)
276 {
277
278 /* Not enabled, return error. */
279 status = TX_FEATURE_NOT_ENABLED;
280 }
281 else if (last_preempted_by != TX_NULL)
282 {
283
284 /* Not enabled, return error. */
285 status = TX_FEATURE_NOT_ENABLED;
286 }
287 else
288 {
289
290 /* Not enabled, return error. */
291 status = TX_FEATURE_NOT_ENABLED;
292 }
293 #endif
294
295 /* Return completion status. */
296 return(status);
297 }
298
299