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