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