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