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