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