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