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 /**   Execution Profile Kit                                               */
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_execution_profile.h"
29 
30 /* The thread execution profile kit is designed to track thread execution time
31    based on the hardware timer defined by TX_EXECUTION_TIME_SOURCE and
32    TX_EXECUTION_MAX_TIME_SOURCE below. When the thread's total time reaches
33    the maximum value, it remains there until the time is reset to 0 via a call
34    to tx_thread_execution_time_reset. There are several assumptions to the
35    operation of this kit, as follows:
36 
37    1. In tx_port.h replace:
38 
39         #define TX_THREAD_EXTENSION_3"
40 
41       with:
42 
43         #define TX_THREAD_EXTENSION_3           unsigned long long  tx_thread_execution_time_total; \
44                                                 unsigned long       tx_thread_execution_time_last_start;
45 
46         Note: if 64-bit time source is present, the tx_thread_execution_time_last_start type should be unsigned long long.
47 
48    2. The TX_EXECUTION_TIME_SOURCE and TX_EXECUTION_MAX_TIME_SOURCE macros are
49       defined to utilize a local hardware time source.
50 
51    3. ThreadX 5.4 (or later) is being used, with the assembly code enabled to
52       call the following routines from assembly code:
53 
54             VOID  _tx_execution_thread_enter(void);
55             VOID  _tx_execution_thread_exit(void);
56             VOID  _tx_execution_isr_enter(void);
57             VOID  _tx_execution_isr_exit(void);
58 
59     4. The ThreadX library assembly code must be rebuilt with TX_ENABLE_EXECUTION_CHANGE_NOTIFY so
60        that these macros are expanded in the TX_THREAD structure and so the assembly code macros
61        are enabled to call the execution profile routines.
62 
63     5. Add tx_execution_profile.c to the application build.  */
64 
65 
66 /* Externally reference several internal ThreadX variables.  */
67 
68 extern ULONG                            _tx_thread_system_state[TX_THREAD_SMP_MAX_CORES];
69 extern UINT                             _tx_thread_preempt_disable;
70 extern TX_THREAD                        *_tx_thread_current_ptr[TX_THREAD_SMP_MAX_CORES];
71 extern TX_THREAD                        *_tx_thread_execute_ptr[TX_THREAD_SMP_MAX_CORES];
72 extern TX_THREAD                        *_tx_thread_created_ptr;
73 extern ULONG                            _tx_thread_created_count;
74 
75 
76 /* Define the total time for all threads.  This is accumulated as each thread's total time is accumulated.  */
77 
78 EXECUTION_TIME                      _tx_execution_thread_time_total[TX_THREAD_SMP_MAX_CORES];
79 
80 
81 /* Define the ISR time gathering information. This is setup to track total ISR time presently, but
82    could easily be expanded to track different ISRs. Also, only ISRs that utilize _tx_thread_context_save
83    and _tx_thread_context_restore are tracked by this utility.  */
84 
85 EXECUTION_TIME                      _tx_execution_isr_time_total[TX_THREAD_SMP_MAX_CORES];
86 EXECUTION_TIME_SOURCE_TYPE          _tx_execution_isr_time_last_start[TX_THREAD_SMP_MAX_CORES];
87 
88 
89 /* Define the system idle time gathering information. For idle time that exceeds the range of the timer
90    source, another timer source may be needed. In addition, the total thread execution time added to the
91    total ISR time, less the total system time is also a measure of idle time.  */
92 
93 EXECUTION_TIME                      _tx_execution_idle_time_total[TX_THREAD_SMP_MAX_CORES];
94 EXECUTION_TIME_SOURCE_TYPE          _tx_execution_idle_time_last_start[TX_THREAD_SMP_MAX_CORES];
95 
96 
97 /**************************************************************************/
98 /*                                                                        */
99 /*  FUNCTION                                               RELEASE        */
100 /*                                                                        */
101 /*    _tx_execution_thread_enter                         PORTABLE SMP     */
102 /*                                                           6.1.12       */
103 /*  AUTHOR                                                                */
104 /*                                                                        */
105 /*    William E. Lamie, Microsoft Corporation                             */
106 /*                                                                        */
107 /*  DESCRIPTION                                                           */
108 /*                                                                        */
109 /*    This function is called whenever thread execution starts.           */
110 /*                                                                        */
111 /*  INPUT                                                                 */
112 /*                                                                        */
113 /*    None                                                                */
114 /*                                                                        */
115 /*  OUTPUT                                                                */
116 /*                                                                        */
117 /*    None                                                                */
118 /*                                                                        */
119 /*  CALLS                                                                 */
120 /*                                                                        */
121 /*    None                                                                */
122 /*                                                                        */
123 /*  CALLED BY                                                             */
124 /*                                                                        */
125 /*    _tx_thread_schedule               Thread scheduling                 */
126 /*                                                                        */
127 /*  RELEASE HISTORY                                                       */
128 /*                                                                        */
129 /*    DATE              NAME                      DESCRIPTION             */
130 /*                                                                        */
131 /*  07-29-2022      William E. Lamie        Initial Version 6.1.12        */
132 /*                                                                        */
133 /**************************************************************************/
_tx_execution_thread_enter(void)134 VOID  _tx_execution_thread_enter(void)
135 {
136 
137 TX_THREAD                   *thread_ptr;
138 EXECUTION_TIME_SOURCE_TYPE  last_start_time;
139 EXECUTION_TIME_SOURCE_TYPE  current_time;
140 EXECUTION_TIME              delta_time;
141 EXECUTION_TIME              total_time;
142 EXECUTION_TIME              new_total_time;
143 UINT                        core;
144 
145 
146     /* Pickup the current time.  */
147     current_time =  TX_EXECUTION_TIME_SOURCE;
148 
149     /* Pickup the core index.  */
150     core =  TX_SMP_CORE_ID;
151 
152     /* Pickup the current thread control block.  */
153     thread_ptr =  _tx_thread_current_ptr[core];
154 
155     /* This thread is being scheduled.  Simply setup the last start time in the
156        thread control block.  */
157     thread_ptr -> tx_thread_execution_time_last_start =  current_time;
158 
159     /* Pickup the last idle start time.  */
160     last_start_time =  _tx_execution_idle_time_last_start[core];
161 
162     /* Determine if idle time is being measured.  */
163     if (last_start_time)
164     {
165 
166         /* Determine how to calculate the difference.  */
167         if (current_time >= last_start_time)
168         {
169 
170             /* Simply subtract.  */
171             delta_time =  (EXECUTION_TIME) (current_time - last_start_time);
172         }
173         else
174         {
175 
176             /* Timer wrapped, compute the delta assuming incrementing time counter.  */
177             delta_time =  (EXECUTION_TIME) (current_time + (((EXECUTION_TIME_SOURCE_TYPE) TX_EXECUTION_MAX_TIME_SOURCE) - last_start_time));
178         }
179 
180         /* Pickup the total time.  */
181         total_time =  _tx_execution_idle_time_total[core];
182 
183         /* Now compute the new total time.  */
184         new_total_time =  total_time + delta_time;
185 
186         /* Determine if a rollover on the total time is present.  */
187         if (new_total_time < total_time)
188         {
189 
190             /* Rollover. Set the total time to max value.  */
191             new_total_time =  (EXECUTION_TIME) TX_EXECUTION_MAX_TIME_SOURCE;
192         }
193 
194         /* Now store back the total idle time.  */
195         _tx_execution_idle_time_total[core] =  new_total_time;
196 
197         /* Disable the idle time measurement.  */
198         _tx_execution_idle_time_last_start[core] =  0;
199     }
200 }
201 
202 
203 /**************************************************************************/
204 /*                                                                        */
205 /*  FUNCTION                                               RELEASE        */
206 /*                                                                        */
207 /*    _tx_execution_thread_exit                          PORTABLE SMP     */
208 /*                                                           6.1.12       */
209 /*  AUTHOR                                                                */
210 /*                                                                        */
211 /*    William E. Lamie, Microsoft Corporation                             */
212 /*                                                                        */
213 /*  DESCRIPTION                                                           */
214 /*                                                                        */
215 /*    This function is called whenever a thread execution ends.           */
216 /*                                                                        */
217 /*  INPUT                                                                 */
218 /*                                                                        */
219 /*    None                                                                */
220 /*                                                                        */
221 /*  OUTPUT                                                                */
222 /*                                                                        */
223 /*    None                                                                */
224 /*                                                                        */
225 /*  CALLS                                                                 */
226 /*                                                                        */
227 /*    None                                                                */
228 /*                                                                        */
229 /*  CALLED BY                                                             */
230 /*                                                                        */
231 /*    _tx_thread_system_return          Thread exiting                    */
232 /*                                                                        */
233 /*  RELEASE HISTORY                                                       */
234 /*                                                                        */
235 /*    DATE              NAME                      DESCRIPTION             */
236 /*                                                                        */
237 /*  07-29-2022      William E. Lamie        Initial Version 6.1.12        */
238 /*                                                                        */
239 /**************************************************************************/
_tx_execution_thread_exit(void)240 VOID  _tx_execution_thread_exit(void)
241 {
242 
243 TX_THREAD                   *thread_ptr;
244 EXECUTION_TIME              total_time;
245 EXECUTION_TIME              new_total_time;
246 EXECUTION_TIME_SOURCE_TYPE  last_start_time;
247 EXECUTION_TIME_SOURCE_TYPE  current_time;
248 EXECUTION_TIME              delta_time;
249 UINT                        core;
250 
251 
252     /* Pickup the core index.  */
253     core =  TX_SMP_CORE_ID;
254 
255     /* Pickup the current thread control block.  */
256     thread_ptr =  _tx_thread_current_ptr[core];
257 
258     /* Determine if there is a thread.  */
259     if (thread_ptr)
260     {
261 
262         /* Pickup the current time.  */
263         current_time =  TX_EXECUTION_TIME_SOURCE;
264 
265         /* Pickup the last start time.  */
266         last_start_time =  thread_ptr -> tx_thread_execution_time_last_start;
267 
268         /* Determine if there is an actual start time.  */
269         if (last_start_time)
270         {
271 
272             /* Clear the last start time.  */
273             thread_ptr -> tx_thread_execution_time_last_start =  0;
274 
275             /* Determine how to calculate the difference.  */
276             if (current_time >= last_start_time)
277             {
278 
279                 /* Simply subtract.  */
280                 delta_time =  (EXECUTION_TIME) (current_time - last_start_time);
281             }
282             else
283             {
284 
285                 /* Timer wrapped, compute the delta assuming incrementing time counter.  */
286                 delta_time =  (EXECUTION_TIME) (current_time + (((EXECUTION_TIME_SOURCE_TYPE) TX_EXECUTION_MAX_TIME_SOURCE) - last_start_time));
287             }
288 
289             /* Pickup the total time.  */
290             total_time =  thread_ptr -> tx_thread_execution_time_total;
291 
292             /* Now compute the new total time.  */
293             new_total_time =  total_time + delta_time;
294 
295             /* Determine if a rollover on the total time is present.  */
296             if (new_total_time < total_time)
297             {
298 
299                 /* Rollover. Set the total time to max value.  */
300                 new_total_time =  (EXECUTION_TIME) TX_EXECUTION_MAX_TIME_SOURCE;
301             }
302 
303             /* Store back the new total time.  */
304             thread_ptr -> tx_thread_execution_time_total =  new_total_time;
305 
306             /* Now accumulate this thread's execution time into the total thread execution time.   */
307             new_total_time =  _tx_execution_thread_time_total[core] + delta_time;
308 
309             /* Determine if a rollover on the total time is present.  */
310             if (new_total_time < _tx_execution_thread_time_total[core])
311             {
312 
313                 /* Rollover. Set the total time to max value.  */
314                 new_total_time =  (EXECUTION_TIME) TX_EXECUTION_MAX_TIME_SOURCE;
315             }
316 
317             /* Store back the new total time.  */
318             _tx_execution_thread_time_total[core] =  new_total_time;
319         }
320 
321         /* Is the system now idle?  */
322         if (_tx_thread_execute_ptr[core] == TX_NULL)
323         {
324 
325             /* Yes, idle system. Pickup the start of idle time.  */
326             _tx_execution_idle_time_last_start[core] =  TX_EXECUTION_TIME_SOURCE;
327         }
328     }
329 }
330 
331 
332 /**************************************************************************/
333 /*                                                                        */
334 /*  FUNCTION                                               RELEASE        */
335 /*                                                                        */
336 /*    _tx_execution_isr_enter                            PORTABLE SMP     */
337 /*                                                           6.1.12       */
338 /*  AUTHOR                                                                */
339 /*                                                                        */
340 /*    William E. Lamie, Microsoft Corporation                             */
341 /*                                                                        */
342 /*  DESCRIPTION                                                           */
343 /*                                                                        */
344 /*    This function is called whenever ISR processing starts.             */
345 /*                                                                        */
346 /*  INPUT                                                                 */
347 /*                                                                        */
348 /*    None                                                                */
349 /*                                                                        */
350 /*  OUTPUT                                                                */
351 /*                                                                        */
352 /*    None                                                                */
353 /*                                                                        */
354 /*  CALLS                                                                 */
355 /*                                                                        */
356 /*    None                                                                */
357 /*                                                                        */
358 /*  CALLED BY                                                             */
359 /*                                                                        */
360 /*    _tx_thread_context_save           ISR context save                  */
361 /*                                                                        */
362 /*  RELEASE HISTORY                                                       */
363 /*                                                                        */
364 /*    DATE              NAME                      DESCRIPTION             */
365 /*                                                                        */
366 /*  07-29-2022      William E. Lamie        Initial Version 6.1.12        */
367 /*                                                                        */
368 /**************************************************************************/
_tx_execution_isr_enter(void)369 VOID  _tx_execution_isr_enter(void)
370 {
371 
372 TX_THREAD                   *thread_ptr;
373 EXECUTION_TIME_SOURCE_TYPE  current_time;
374 EXECUTION_TIME              total_time;
375 EXECUTION_TIME              new_total_time;
376 EXECUTION_TIME_SOURCE_TYPE  last_start_time;
377 EXECUTION_TIME              delta_time;
378 UINT                        core;
379 
380 
381     /* Pickup the core index.  */
382     core =  TX_SMP_CORE_ID;
383 
384     /* Determine if this is the first interrupt. Nested interrupts are all treated as
385        general interrupt processing.  */
386     if (_tx_thread_system_state[core] == 1)
387     {
388         /* Pickup the current time.  */
389         current_time =  TX_EXECUTION_TIME_SOURCE;
390 
391         /* Pickup the current thread control block.  */
392         thread_ptr =  _tx_thread_current_ptr[core];
393 
394         /* Determine if a thread was interrupted.  */
395         if (thread_ptr)
396         {
397 
398             /* Pickup the last start time.  */
399             last_start_time =  thread_ptr -> tx_thread_execution_time_last_start;
400 
401             /* Determine if there is an actual start time.  */
402             if (last_start_time)
403             {
404 
405                 /* Clear the last start time.  */
406                 thread_ptr -> tx_thread_execution_time_last_start =  0;
407 
408                 /* Determine how to calculate the difference.  */
409                 if (current_time >= last_start_time)
410                 {
411 
412                     /* Simply subtract.  */
413                     delta_time =  (EXECUTION_TIME) (current_time - last_start_time);
414                 }
415                 else
416                 {
417 
418                     /* Timer wrapped, compute the delta assuming incrementing time counter.  */
419                     delta_time =  (EXECUTION_TIME) (current_time + (((EXECUTION_TIME_SOURCE_TYPE) TX_EXECUTION_MAX_TIME_SOURCE) - last_start_time));
420                 }
421 
422                 /* Pickup the total time.  */
423                 total_time =  thread_ptr -> tx_thread_execution_time_total;
424 
425                 /* Now compute the new total time.  */
426                 new_total_time =  total_time + delta_time;
427 
428                 /* Determine if a rollover on the total time is present.  */
429                 if (new_total_time < total_time)
430                 {
431 
432                     /* Rollover. Set the total time to max value.  */
433                     new_total_time =  (EXECUTION_TIME) TX_EXECUTION_MAX_TIME_SOURCE;
434                 }
435 
436                 /* Store back the new total time.  */
437                 thread_ptr -> tx_thread_execution_time_total =  new_total_time;
438 
439                 /* Now accumulate this thread's execution time into the total thread execution time.   */
440                 new_total_time =  _tx_execution_thread_time_total[core] + delta_time;
441 
442                 /* Determine if a rollover on the total time is present.  */
443                 if (new_total_time < _tx_execution_thread_time_total[core])
444                 {
445 
446                     /* Rollover. Set the total time to max value.  */
447                     new_total_time =  (EXECUTION_TIME) TX_EXECUTION_MAX_TIME_SOURCE;
448                 }
449 
450                 /* Store back the new total time.  */
451                 _tx_execution_thread_time_total[core] =  new_total_time;
452             }
453         }
454 
455         /* Has idle time started?  */
456         else if (_tx_execution_idle_time_last_start[core])
457         {
458 
459             /* Pickup the last idle start time.  */
460             last_start_time =  _tx_execution_idle_time_last_start[core];
461 
462             /* Determine how to calculate the difference.  */
463             if (current_time >= last_start_time)
464             {
465 
466                 /* Simply subtract.  */
467                 delta_time =  (EXECUTION_TIME) (current_time - last_start_time);
468             }
469             else
470             {
471 
472                 /* Timer wrapped, compute the delta assuming incrementing time counter.  */
473                 delta_time =  (EXECUTION_TIME) (current_time + (((EXECUTION_TIME_SOURCE_TYPE) TX_EXECUTION_MAX_TIME_SOURCE) - last_start_time));
474             }
475 
476             /* Pickup the total time.  */
477             total_time =  _tx_execution_idle_time_total[core];
478 
479             /* Now compute the new total time.  */
480             new_total_time =  total_time + delta_time;
481 
482             /* Determine if a rollover on the total time is present.  */
483             if (new_total_time < total_time)
484             {
485 
486                 /* Rollover. Set the total time to max value.  */
487                 new_total_time =  (EXECUTION_TIME) TX_EXECUTION_MAX_TIME_SOURCE;
488             }
489 
490             /* Now store back the total idle time.  */
491             _tx_execution_idle_time_total[core] =  new_total_time;
492 
493             /* Disable the idle time measurement.  */
494             _tx_execution_idle_time_last_start[core] =  0;
495         }
496 
497         /* Save the ISR start time.  */
498         _tx_execution_isr_time_last_start[core] =  current_time;
499     }
500 }
501 
502 
503 /**************************************************************************/
504 /*                                                                        */
505 /*  FUNCTION                                               RELEASE        */
506 /*                                                                        */
507 /*    _tx_execution_isr_exit                             PORTABLE SMP     */
508 /*                                                           6.1.12       */
509 /*  AUTHOR                                                                */
510 /*                                                                        */
511 /*    William E. Lamie, Microsoft Corporation                             */
512 /*                                                                        */
513 /*  DESCRIPTION                                                           */
514 /*                                                                        */
515 /*    This function is called whenever ISR processing ends.               */
516 /*                                                                        */
517 /*  INPUT                                                                 */
518 /*                                                                        */
519 /*    None                                                                */
520 /*                                                                        */
521 /*  OUTPUT                                                                */
522 /*                                                                        */
523 /*    None                                                                */
524 /*                                                                        */
525 /*  CALLS                                                                 */
526 /*                                                                        */
527 /*    None                                                                */
528 /*                                                                        */
529 /*  CALLED BY                                                             */
530 /*                                                                        */
531 /*    _tx_thread_context_restore        Thread de-scheduling              */
532 /*                                                                        */
533 /*  RELEASE HISTORY                                                       */
534 /*                                                                        */
535 /*    DATE              NAME                      DESCRIPTION             */
536 /*                                                                        */
537 /*  07-29-2022      William E. Lamie        Initial Version 6.1.12        */
538 /*                                                                        */
539 /**************************************************************************/
_tx_execution_isr_exit(void)540 VOID  _tx_execution_isr_exit(void)
541 {
542 
543 TX_THREAD                   *thread_ptr;
544 EXECUTION_TIME              total_time;
545 EXECUTION_TIME              new_total_time;
546 EXECUTION_TIME_SOURCE_TYPE  last_start_time;
547 EXECUTION_TIME_SOURCE_TYPE  current_time;
548 EXECUTION_TIME              delta_time;
549 UINT                        core;
550 
551 
552     /* Pickup the core index.  */
553     core =  TX_SMP_CORE_ID;
554 
555     /* Determine if this is the first interrupt. Nested interrupts are all treated as
556        general interrupt processing.  */
557     if (_tx_thread_system_state[core] == 1)
558     {
559 
560         /* Pickup the current time.  */
561         current_time =  TX_EXECUTION_TIME_SOURCE;
562 
563         /* Pickup the last start time.  */
564         last_start_time =  _tx_execution_isr_time_last_start[core];
565 
566         /* Determine how to calculate the difference.  */
567         if (current_time >= last_start_time)
568         {
569 
570            /* Simply subtract.  */
571            delta_time =  (EXECUTION_TIME) (current_time - last_start_time);
572         }
573         else
574         {
575 
576             /* Timer wrapped, compute the delta assuming incrementing time counter.  */
577             delta_time =  (EXECUTION_TIME) (current_time + (((EXECUTION_TIME_SOURCE_TYPE) TX_EXECUTION_MAX_TIME_SOURCE) - last_start_time));
578         }
579 
580         /* Pickup the total time.  */
581         total_time =  _tx_execution_isr_time_total[core];
582 
583         /* Now compute the new total time.  */
584         new_total_time =  total_time + delta_time;
585 
586         /* Determine if a rollover on the total time is present.  */
587         if (new_total_time < total_time)
588         {
589 
590             /* Rollover. Set the total time to max value.  */
591             new_total_time =  (EXECUTION_TIME) TX_EXECUTION_MAX_TIME_SOURCE;
592         }
593 
594         /* Store back the new total time.  */
595         _tx_execution_isr_time_total[core] =  new_total_time;
596 
597         /* Pickup the current thread control block.  */
598         thread_ptr =  _tx_thread_current_ptr[core];
599 
600         /* Was a thread interrupted?  */
601         if (thread_ptr)
602         {
603 
604             /* Now determine if the thread will execution is going to occur immediately.  */
605             if ((thread_ptr == _tx_thread_execute_ptr[core]) || (_tx_thread_preempt_disable))
606             {
607 
608                 /* Yes, setup the thread last start time in the thread control block.  */
609                 thread_ptr -> tx_thread_execution_time_last_start =  current_time;
610             }
611         }
612 
613         /* Determine if the system is now idle.  */
614         if (_tx_thread_execute_ptr[core] == TX_NULL)
615         {
616 
617             /* Yes, idle system. Pickup the start of idle time.  */
618             _tx_execution_idle_time_last_start[core] =  TX_EXECUTION_TIME_SOURCE;
619         }
620     }
621 }
622 
623 
624 /**************************************************************************/
625 /*                                                                        */
626 /*  FUNCTION                                               RELEASE        */
627 /*                                                                        */
628 /*    _tx_execution_thread_time_reset                    PORTABLE SMP     */
629 /*                                                           6.1.12       */
630 /*  AUTHOR                                                                */
631 /*                                                                        */
632 /*    William E. Lamie, Microsoft Corporation                             */
633 /*                                                                        */
634 /*  DESCRIPTION                                                           */
635 /*                                                                        */
636 /*    This function resets the execution time of the specified thread.    */
637 /*                                                                        */
638 /*  INPUT                                                                 */
639 /*                                                                        */
640 /*    thread_ptr                        Pointer to thread                 */
641 /*                                                                        */
642 /*  OUTPUT                                                                */
643 /*                                                                        */
644 /*    status                            Completion status                 */
645 /*                                                                        */
646 /*  CALLS                                                                 */
647 /*                                                                        */
648 /*    None                                                                */
649 /*                                                                        */
650 /*  CALLED BY                                                             */
651 /*                                                                        */
652 /*    Application code                                                    */
653 /*                                                                        */
654 /*  RELEASE HISTORY                                                       */
655 /*                                                                        */
656 /*    DATE              NAME                      DESCRIPTION             */
657 /*                                                                        */
658 /*  07-29-2022      William E. Lamie        Initial Version 6.1.12        */
659 /*                                                                        */
660 /**************************************************************************/
_tx_execution_thread_time_reset(TX_THREAD * thread_ptr)661 UINT  _tx_execution_thread_time_reset(TX_THREAD *thread_ptr)
662 {
663 
664     /* Reset the total time to 0.  */
665     thread_ptr -> tx_thread_execution_time_total =  0;
666 
667     /* Return success.  */
668     return(TX_SUCCESS);
669 }
670 
671 
672 /**************************************************************************/
673 /*                                                                        */
674 /*  FUNCTION                                               RELEASE        */
675 /*                                                                        */
676 /*    _tx_execution_thread_total_time_reset              PORTABLE SMP     */
677 /*                                                           6.1.12       */
678 /*  AUTHOR                                                                */
679 /*                                                                        */
680 /*    William E. Lamie, Microsoft Corporation                             */
681 /*                                                                        */
682 /*  DESCRIPTION                                                           */
683 /*                                                                        */
684 /*    This function resets the total thread execution time.               */
685 /*                                                                        */
686 /*  INPUT                                                                 */
687 /*                                                                        */
688 /*    None                                                                */
689 /*                                                                        */
690 /*  OUTPUT                                                                */
691 /*                                                                        */
692 /*    status                            Completion status                 */
693 /*                                                                        */
694 /*  CALLS                                                                 */
695 /*                                                                        */
696 /*    None                                                                */
697 /*                                                                        */
698 /*  CALLED BY                                                             */
699 /*                                                                        */
700 /*    Application code                                                    */
701 /*                                                                        */
702 /*  RELEASE HISTORY                                                       */
703 /*                                                                        */
704 /*    DATE              NAME                      DESCRIPTION             */
705 /*                                                                        */
706 /*  07-29-2022      William E. Lamie        Initial Version 6.1.12        */
707 /*                                                                        */
708 /**************************************************************************/
_tx_execution_thread_total_time_reset(void)709 UINT  _tx_execution_thread_total_time_reset(void)
710 {
711 
712 TX_INTERRUPT_SAVE_AREA
713 
714 TX_THREAD       *thread_ptr;
715 UINT            total_threads;
716 UINT            core;
717 
718 
719     /* Disable interrupts.  */
720     TX_DISABLE
721 
722     /* Reset the total time for all cores.  */
723     for (core = 0; core < TX_THREAD_SMP_MAX_CORES; core++)
724     {
725 
726         _tx_execution_thread_time_total[core] =  0;
727     }
728 
729     /* Loop through threads to clear their accumulated time.  */
730     total_threads =      _tx_thread_created_count;
731     thread_ptr =         _tx_thread_created_ptr;
732     while (total_threads--)
733     {
734         thread_ptr -> tx_thread_execution_time_total =  0;
735         thread_ptr =  thread_ptr -> tx_thread_created_next;
736     }
737 
738     /* Restore interrupts.  */
739     TX_RESTORE
740 
741     /* Return success.  */
742     return(TX_SUCCESS);
743 }
744 
745 
746 /**************************************************************************/
747 /*                                                                        */
748 /*  FUNCTION                                               RELEASE        */
749 /*                                                                        */
750 /*    _tx_execution_isr_time_reset                       PORTABLE SMP     */
751 /*                                                           6.1.12       */
752 /*  AUTHOR                                                                */
753 /*                                                                        */
754 /*    William E. Lamie, Microsoft Corporation                             */
755 /*                                                                        */
756 /*  DESCRIPTION                                                           */
757 /*                                                                        */
758 /*    This function resets the execution time of the ISR calculation.     */
759 /*                                                                        */
760 /*  INPUT                                                                 */
761 /*                                                                        */
762 /*    None                                                                */
763 /*                                                                        */
764 /*  OUTPUT                                                                */
765 /*                                                                        */
766 /*    status                            Completion status                 */
767 /*                                                                        */
768 /*  CALLS                                                                 */
769 /*                                                                        */
770 /*    None                                                                */
771 /*                                                                        */
772 /*  CALLED BY                                                             */
773 /*                                                                        */
774 /*    Application code                                                    */
775 /*                                                                        */
776 /*  RELEASE HISTORY                                                       */
777 /*                                                                        */
778 /*    DATE              NAME                      DESCRIPTION             */
779 /*                                                                        */
780 /*  07-29-2022      William E. Lamie        Initial Version 6.1.12        */
781 /*                                                                        */
782 /**************************************************************************/
_tx_execution_isr_time_reset(void)783 UINT  _tx_execution_isr_time_reset(void)
784 {
785 
786 TX_INTERRUPT_SAVE_AREA
787 
788 UINT            core;
789 
790     /* Disable interrupts.  */
791     TX_DISABLE
792 
793     /* Reset the ISR total time to 0.  */
794     for (core = 0; core < TX_THREAD_SMP_MAX_CORES; core++)
795     {
796 
797         _tx_execution_isr_time_total[core] =  0;
798     }
799 
800     /* Restore interrupts.  */
801     TX_RESTORE
802 
803     /* Return success.  */
804     return(TX_SUCCESS);
805 }
806 
807 
808 /**************************************************************************/
809 /*                                                                        */
810 /*  FUNCTION                                               RELEASE        */
811 /*                                                                        */
812 /*    _tx_execution_idle_time_reset                      PORTABLE SMP     */
813 /*                                                           6.1.12       */
814 /*  AUTHOR                                                                */
815 /*                                                                        */
816 /*    William E. Lamie, Microsoft Corporation                             */
817 /*                                                                        */
818 /*  DESCRIPTION                                                           */
819 /*                                                                        */
820 /*    This function resets the idle execution time calculation.           */
821 /*                                                                        */
822 /*  INPUT                                                                 */
823 /*                                                                        */
824 /*    None                                                                */
825 /*                                                                        */
826 /*  OUTPUT                                                                */
827 /*                                                                        */
828 /*    status                            Completion status                 */
829 /*                                                                        */
830 /*  CALLS                                                                 */
831 /*                                                                        */
832 /*    None                                                                */
833 /*                                                                        */
834 /*  CALLED BY                                                             */
835 /*                                                                        */
836 /*    Application code                                                    */
837 /*                                                                        */
838 /*  RELEASE HISTORY                                                       */
839 /*                                                                        */
840 /*    DATE              NAME                      DESCRIPTION             */
841 /*                                                                        */
842 /*  07-29-2022      William E. Lamie        Initial Version 6.1.12        */
843 /*                                                                        */
844 /**************************************************************************/
_tx_execution_idle_time_reset(void)845 UINT  _tx_execution_idle_time_reset(void)
846 {
847 
848 TX_INTERRUPT_SAVE_AREA
849 
850 UINT            core;
851 
852     /* Disable interrupts.  */
853     TX_DISABLE
854 
855     /* Reset the idle total time to 0.  */
856     for (core = 0; core < TX_THREAD_SMP_MAX_CORES; core++)
857     {
858 
859         _tx_execution_idle_time_total[core] =  0;
860     }
861 
862     /* Restore interrupts.  */
863     TX_RESTORE
864 
865     /* Return success.  */
866     return(TX_SUCCESS);
867 }
868 
869 
870 /**************************************************************************/
871 /*                                                                        */
872 /*  FUNCTION                                               RELEASE        */
873 /*                                                                        */
874 /*    _tx_execution_thread_time_get                      PORTABLE SMP     */
875 /*                                                           6.1.12       */
876 /*  AUTHOR                                                                */
877 /*                                                                        */
878 /*    William E. Lamie, Microsoft Corporation                             */
879 /*                                                                        */
880 /*  DESCRIPTION                                                           */
881 /*                                                                        */
882 /*    This function gets the execution time of the specified thread.      */
883 /*                                                                        */
884 /*  INPUT                                                                 */
885 /*                                                                        */
886 /*    thread_ptr                        Pointer to the thread             */
887 /*    total_time                        Destination for total time        */
888 /*                                                                        */
889 /*  OUTPUT                                                                */
890 /*                                                                        */
891 /*    status                            Completion status                 */
892 /*                                                                        */
893 /*  CALLS                                                                 */
894 /*                                                                        */
895 /*    None                                                                */
896 /*                                                                        */
897 /*  CALLED BY                                                             */
898 /*                                                                        */
899 /*    Application code                                                    */
900 /*                                                                        */
901 /*  RELEASE HISTORY                                                       */
902 /*                                                                        */
903 /*    DATE              NAME                      DESCRIPTION             */
904 /*                                                                        */
905 /*  07-29-2022      William E. Lamie        Initial Version 6.1.12        */
906 /*                                                                        */
907 /**************************************************************************/
_tx_execution_thread_time_get(TX_THREAD * thread_ptr,EXECUTION_TIME * total_time)908 UINT  _tx_execution_thread_time_get(TX_THREAD *thread_ptr, EXECUTION_TIME *total_time)
909 {
910 
911     /* Return the total time.  */
912     *total_time =  thread_ptr -> tx_thread_execution_time_total;
913 
914     /* Return success.  */
915     return(TX_SUCCESS);
916 }
917 
918 
919 /**************************************************************************/
920 /*                                                                        */
921 /*  FUNCTION                                               RELEASE        */
922 /*                                                                        */
923 /*    _tx_execution_thread_total_time_get                PORTABLE SMP     */
924 /*                                                           6.1.12       */
925 /*  AUTHOR                                                                */
926 /*                                                                        */
927 /*    William E. Lamie, Microsoft Corporation                             */
928 /*                                                                        */
929 /*  DESCRIPTION                                                           */
930 /*                                                                        */
931 /*    This function gets the execution time of all threads.               */
932 /*                                                                        */
933 /*  INPUT                                                                 */
934 /*                                                                        */
935 /*    total_time                        Destination for total time        */
936 /*                                                                        */
937 /*  OUTPUT                                                                */
938 /*                                                                        */
939 /*    status                            Completion status                 */
940 /*                                                                        */
941 /*  CALLS                                                                 */
942 /*                                                                        */
943 /*    None                                                                */
944 /*                                                                        */
945 /*  CALLED BY                                                             */
946 /*                                                                        */
947 /*    Application code                                                    */
948 /*                                                                        */
949 /*  RELEASE HISTORY                                                       */
950 /*                                                                        */
951 /*    DATE              NAME                      DESCRIPTION             */
952 /*                                                                        */
953 /*  07-29-2022      William E. Lamie        Initial Version 6.1.12        */
954 /*                                                                        */
955 /**************************************************************************/
_tx_execution_thread_total_time_get(EXECUTION_TIME * total_time)956 UINT  _tx_execution_thread_total_time_get(EXECUTION_TIME *total_time)
957 {
958 
959 TX_INTERRUPT_SAVE_AREA
960 
961 UINT            core;
962 
963     /* Disable interrupts.  */
964     TX_DISABLE
965 
966     /* Return the total thread time.  */
967     for (core = 0; core < TX_THREAD_SMP_MAX_CORES; core++)
968     {
969 
970         *total_time =  _tx_execution_thread_time_total[core];
971     }
972 
973     /* Restore interrupts.  */
974     TX_RESTORE
975 
976     /* Return success.  */
977     return(TX_SUCCESS);
978 }
979 
980 
981 /**************************************************************************/
982 /*                                                                        */
983 /*  FUNCTION                                               RELEASE        */
984 /*                                                                        */
985 /*    _tx_execution_isr_time_get                         PORTABLE SMP     */
986 /*                                                           6.1.12       */
987 /*  AUTHOR                                                                */
988 /*                                                                        */
989 /*    William E. Lamie, Microsoft Corporation                             */
990 /*                                                                        */
991 /*  DESCRIPTION                                                           */
992 /*                                                                        */
993 /*    This function gets the execution time of all ISRs.                  */
994 /*                                                                        */
995 /*  INPUT                                                                 */
996 /*                                                                        */
997 /*    total_time                        Destination for total time        */
998 /*                                                                        */
999 /*  OUTPUT                                                                */
1000 /*                                                                        */
1001 /*    status                            Completion status                 */
1002 /*                                                                        */
1003 /*  CALLS                                                                 */
1004 /*                                                                        */
1005 /*    None                                                                */
1006 /*                                                                        */
1007 /*  CALLED BY                                                             */
1008 /*                                                                        */
1009 /*    Application code                                                    */
1010 /*                                                                        */
1011 /*  RELEASE HISTORY                                                       */
1012 /*                                                                        */
1013 /*    DATE              NAME                      DESCRIPTION             */
1014 /*                                                                        */
1015 /*  07-29-2022      William E. Lamie        Initial Version 6.1.12        */
1016 /*                                                                        */
1017 /**************************************************************************/
_tx_execution_isr_time_get(EXECUTION_TIME * total_time)1018 UINT  _tx_execution_isr_time_get(EXECUTION_TIME *total_time)
1019 {
1020 
1021 TX_INTERRUPT_SAVE_AREA
1022 
1023 UINT            core;
1024 
1025     /* Disable interrupts.  */
1026     TX_DISABLE
1027 
1028     /* Return the total ISR time.  */
1029     for (core = 0; core < TX_THREAD_SMP_MAX_CORES; core++)
1030     {
1031 
1032         /* Return the total time.  */
1033         *total_time =  _tx_execution_isr_time_total[core];
1034     }
1035 
1036     /* Restore interrupts.  */
1037     TX_RESTORE
1038 
1039     /* Return success.  */
1040     return(TX_SUCCESS);
1041 }
1042 
1043 
1044 /**************************************************************************/
1045 /*                                                                        */
1046 /*  FUNCTION                                               RELEASE        */
1047 /*                                                                        */
1048 /*    _tx_execution_idle_time_get                        PORTABLE SMP     */
1049 /*                                                           6.1.12       */
1050 /*  AUTHOR                                                                */
1051 /*                                                                        */
1052 /*    William E. Lamie, Microsoft Corporation                             */
1053 /*                                                                        */
1054 /*  DESCRIPTION                                                           */
1055 /*                                                                        */
1056 /*    This function gets the total system idle time.                      */
1057 /*                                                                        */
1058 /*  INPUT                                                                 */
1059 /*                                                                        */
1060 /*    total_time                        Destination for total time        */
1061 /*                                                                        */
1062 /*  OUTPUT                                                                */
1063 /*                                                                        */
1064 /*    status                            Completion status                 */
1065 /*                                                                        */
1066 /*  CALLS                                                                 */
1067 /*                                                                        */
1068 /*    None                                                                */
1069 /*                                                                        */
1070 /*  CALLED BY                                                             */
1071 /*                                                                        */
1072 /*    Application code                                                    */
1073 /*                                                                        */
1074 /*  RELEASE HISTORY                                                       */
1075 /*                                                                        */
1076 /*    DATE              NAME                      DESCRIPTION             */
1077 /*                                                                        */
1078 /*  07-29-2022      William E. Lamie        Initial Version 6.1.12        */
1079 /*                                                                        */
1080 /**************************************************************************/
_tx_execution_idle_time_get(EXECUTION_TIME * total_time)1081 UINT  _tx_execution_idle_time_get(EXECUTION_TIME *total_time)
1082 {
1083 
1084 TX_INTERRUPT_SAVE_AREA
1085 
1086 UINT            core;
1087 
1088     /* Disable interrupts.  */
1089     TX_DISABLE
1090 
1091     /* Return the total time.  */
1092     for (core = 0; core < TX_THREAD_SMP_MAX_CORES; core++)
1093     {
1094 
1095         /* Return the total time.  */
1096         *total_time =  _tx_execution_idle_time_total[core];
1097     }
1098 
1099     /* Restore interrupts.  */
1100     TX_RESTORE
1101 
1102     /* Return success.  */
1103     return(TX_SUCCESS);
1104 }
1105 
1106 
1107 /**************************************************************************/
1108 /*                                                                        */
1109 /*  FUNCTION                                               RELEASE        */
1110 /*                                                                        */
1111 /*    _tx_execution_core_thread_total_time_get           PORTABLE SMP     */
1112 /*                                                           6.1.12       */
1113 /*  AUTHOR                                                                */
1114 /*                                                                        */
1115 /*    William E. Lamie, Microsoft Corporation                             */
1116 /*                                                                        */
1117 /*  DESCRIPTION                                                           */
1118 /*                                                                        */
1119 /*    This function gets the total thread execution time of the           */
1120 /*    specified core.                                                     */
1121 /*                                                                        */
1122 /*  INPUT                                                                 */
1123 /*                                                                        */
1124 /*    core                              Specified core                    */
1125 /*    total_time                        Destination for total time        */
1126 /*                                                                        */
1127 /*  OUTPUT                                                                */
1128 /*                                                                        */
1129 /*    status                            Completion status                 */
1130 /*                                                                        */
1131 /*  CALLS                                                                 */
1132 /*                                                                        */
1133 /*    None                                                                */
1134 /*                                                                        */
1135 /*  CALLED BY                                                             */
1136 /*                                                                        */
1137 /*    Application code                                                    */
1138 /*                                                                        */
1139 /*  RELEASE HISTORY                                                       */
1140 /*                                                                        */
1141 /*    DATE              NAME                      DESCRIPTION             */
1142 /*                                                                        */
1143 /*  07-29-2022      William E. Lamie        Initial Version 6.1.12        */
1144 /*                                                                        */
1145 /**************************************************************************/
_tx_execution_core_thread_total_time_get(UINT core,EXECUTION_TIME * total_time)1146 UINT  _tx_execution_core_thread_total_time_get(UINT core, EXECUTION_TIME *total_time)
1147 {
1148 
1149     /* Determine if the core is valid.  */
1150     if (core >= TX_THREAD_SMP_MAX_CORES)
1151     {
1152 
1153         /* Invalid core, return an error.  */
1154         return(TX_NOT_DONE);
1155     }
1156 
1157     /* Return the total thread time for the core.  */
1158     *total_time =  _tx_execution_thread_time_total[core];
1159 
1160     /* Return success.  */
1161     return(TX_SUCCESS);
1162 }
1163 
1164 
1165 /**************************************************************************/
1166 /*                                                                        */
1167 /*  FUNCTION                                               RELEASE        */
1168 /*                                                                        */
1169 /*    _tx_execution_core_isr_time_get                    PORTABLE SMP     */
1170 /*                                                           6.1.12       */
1171 /*  AUTHOR                                                                */
1172 /*                                                                        */
1173 /*    William E. Lamie, Microsoft Corporation                             */
1174 /*                                                                        */
1175 /*  DESCRIPTION                                                           */
1176 /*                                                                        */
1177 /*    This function gets the execution time of ISRs on the specified      */
1178 /*    core.                                                               */
1179 /*                                                                        */
1180 /*  INPUT                                                                 */
1181 /*                                                                        */
1182 /*    core                              Specified core                    */
1183 /*    total_time                        Destination for total time        */
1184 /*                                                                        */
1185 /*  OUTPUT                                                                */
1186 /*                                                                        */
1187 /*    status                            Completion status                 */
1188 /*                                                                        */
1189 /*  CALLS                                                                 */
1190 /*                                                                        */
1191 /*    None                                                                */
1192 /*                                                                        */
1193 /*  CALLED BY                                                             */
1194 /*                                                                        */
1195 /*    Application code                                                    */
1196 /*                                                                        */
1197 /*  RELEASE HISTORY                                                       */
1198 /*                                                                        */
1199 /*    DATE              NAME                      DESCRIPTION             */
1200 /*                                                                        */
1201 /*  07-29-2022      William E. Lamie        Initial Version 6.1.12        */
1202 /*                                                                        */
1203 /**************************************************************************/
_tx_execution_core_isr_time_get(UINT core,EXECUTION_TIME * total_time)1204 UINT  _tx_execution_core_isr_time_get(UINT core, EXECUTION_TIME *total_time)
1205 {
1206 
1207     /* Determine if the core is valid.  */
1208     if (core >= TX_THREAD_SMP_MAX_CORES)
1209     {
1210 
1211         /* Invalid core, return an error.  */
1212         return(TX_NOT_DONE);
1213     }
1214 
1215     /* Return the total ISR time for this core.  */
1216     *total_time =  _tx_execution_isr_time_total[core];
1217 
1218     /* Return success.  */
1219     return(TX_SUCCESS);
1220 }
1221 
1222 
1223 /**************************************************************************/
1224 /*                                                                        */
1225 /*  FUNCTION                                               RELEASE        */
1226 /*                                                                        */
1227 /*    _tx_execution_core_idle_time_get                   PORTABLE SMP     */
1228 /*                                                           6.1.12       */
1229 /*  AUTHOR                                                                */
1230 /*                                                                        */
1231 /*    William E. Lamie, Microsoft Corporation                             */
1232 /*                                                                        */
1233 /*  DESCRIPTION                                                           */
1234 /*                                                                        */
1235 /*    This function gets the idle time of the specified core.             */
1236 /*                                                                        */
1237 /*  INPUT                                                                 */
1238 /*                                                                        */
1239 /*    core                              Specified core                    */
1240 /*    total_time                        Destination for total time        */
1241 /*                                                                        */
1242 /*  OUTPUT                                                                */
1243 /*                                                                        */
1244 /*    status                            Completion status                 */
1245 /*                                                                        */
1246 /*  CALLS                                                                 */
1247 /*                                                                        */
1248 /*    None                                                                */
1249 /*                                                                        */
1250 /*  CALLED BY                                                             */
1251 /*                                                                        */
1252 /*    Application code                                                    */
1253 /*                                                                        */
1254 /*  RELEASE HISTORY                                                       */
1255 /*                                                                        */
1256 /*    DATE              NAME                      DESCRIPTION             */
1257 /*                                                                        */
1258 /*  07-29-2022      William E. Lamie        Initial Version 6.1.12        */
1259 /*                                                                        */
1260 /**************************************************************************/
_tx_execution_core_idle_time_get(UINT core,EXECUTION_TIME * total_time)1261 UINT  _tx_execution_core_idle_time_get(UINT core, EXECUTION_TIME *total_time)
1262 {
1263 
1264     /* Determine if the core is valid.  */
1265     if (core >= TX_THREAD_SMP_MAX_CORES)
1266     {
1267 
1268         /* Invalid core, return an error.  */
1269         return(TX_NOT_DONE);
1270     }
1271 
1272     /* Return the total idle time for this core.  */
1273     *total_time =  _tx_execution_idle_time_total[core];
1274 
1275     /* Return success.  */
1276     return(TX_SUCCESS);
1277 }
1278