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