summaryrefslogtreecommitdiff
path: root/utility/execution_profile_kit/smp_version
diff options
context:
space:
mode:
authorFrédéric Desbiens <[email protected]>2026-03-06 19:27:49 +0100
committerGitHub <[email protected]>2026-03-06 19:27:49 +0100
commit3726d7906b4808bfec7855fc088e073199df9120 (patch)
tree8789bfd03d1d49e1967e80d04aa4ff606fda43eb /utility/execution_profile_kit/smp_version
parent4b6e8100d932a3a67b34c6eb17f84f3bffb9e2ae (diff)
parentc3259a216026372e3833dd8996a68f77e8595fbd (diff)
Merge pull request #510 from eclipse-threadx/devv6.5.0.202601_rel
Merge changes ahead of the v6.5.0.202601 release
Diffstat (limited to 'utility/execution_profile_kit/smp_version')
-rw-r--r--utility/execution_profile_kit/smp_version/tx_execution_profile.c195
-rw-r--r--utility/execution_profile_kit/smp_version/tx_execution_profile.h25
2 files changed, 108 insertions, 112 deletions
diff --git a/utility/execution_profile_kit/smp_version/tx_execution_profile.c b/utility/execution_profile_kit/smp_version/tx_execution_profile.c
index 3b5c05a2..735dbf14 100644
--- a/utility/execution_profile_kit/smp_version/tx_execution_profile.c
+++ b/utility/execution_profile_kit/smp_version/tx_execution_profile.c
@@ -1,10 +1,11 @@
/***************************************************************************
- * Copyright (c) 2024 Microsoft Corporation
- *
+ * Copyright (c) 2024 Microsoft Corporation
+ * Copyright (c) 2026-present Eclipse ThreadX contributors
+ *
* This program and the accompanying materials are made available under the
* terms of the MIT License which is available at
* https://opensource.org/licenses/MIT.
- *
+ *
* SPDX-License-Identifier: MIT
**************************************************************************/
@@ -27,44 +28,44 @@
#include "tx_api.h"
#include "tx_execution_profile.h"
-/* The thread execution profile kit is designed to track thread execution time
- based on the hardware timer defined by TX_EXECUTION_TIME_SOURCE and
- TX_EXECUTION_MAX_TIME_SOURCE below. When the thread's total time reaches
+/* The thread execution profile kit is designed to track thread execution time
+ based on the hardware timer defined by TX_EXECUTION_TIME_SOURCE and
+ TX_EXECUTION_MAX_TIME_SOURCE below. When the thread's total time reaches
the maximum value, it remains there until the time is reset to 0 via a call
- to tx_thread_execution_time_reset. There are several assumptions to the
+ to tx_thread_execution_time_reset. There are several assumptions to the
operation of this kit, as follows:
1. In tx_port.h replace:
-
- #define TX_THREAD_EXTENSION_3"
-
+
+ #define TX_THREAD_EXTENSION_3"
+
with:
-
+
#define TX_THREAD_EXTENSION_3 unsigned long long tx_thread_execution_time_total; \
- unsigned long tx_thread_execution_time_last_start;
-
+ unsigned long tx_thread_execution_time_last_start;
+
Note: if 64-bit time source is present, the tx_thread_execution_time_last_start type should be unsigned long long.
- 2. The TX_EXECUTION_TIME_SOURCE and TX_EXECUTION_MAX_TIME_SOURCE macros are
+ 2. The TX_EXECUTION_TIME_SOURCE and TX_EXECUTION_MAX_TIME_SOURCE macros are
defined to utilize a local hardware time source.
-
+
3. ThreadX 5.4 (or later) is being used, with the assembly code enabled to
call the following routines from assembly code:
-
+
VOID _tx_execution_thread_enter(void);
VOID _tx_execution_thread_exit(void);
VOID _tx_execution_isr_enter(void);
VOID _tx_execution_isr_exit(void);
-
- 4. The ThreadX library assembly code must be rebuilt with TX_ENABLE_EXECUTION_CHANGE_NOTIFY so
- that these macros are expanded in the TX_THREAD structure and so the assembly code macros
- are enabled to call the execution profile routines.
+
+ 4. The ThreadX library assembly code must be rebuilt with TX_ENABLE_EXECUTION_CHANGE_NOTIFY so
+ that these macros are expanded in the TX_THREAD structure and so the assembly code macros
+ are enabled to call the execution profile routines.
5. Add tx_execution_profile.c to the application build. */
/* Externally reference several internal ThreadX variables. */
-
+
extern ULONG _tx_thread_system_state[TX_THREAD_SMP_MAX_CORES];
extern UINT _tx_thread_preempt_disable;
extern TX_THREAD *_tx_thread_current_ptr[TX_THREAD_SMP_MAX_CORES];
@@ -83,11 +84,11 @@ EXECUTION_TIME _tx_execution_thread_time_total[TX_THREAD_SM
and _tx_thread_context_restore are tracked by this utility. */
EXECUTION_TIME _tx_execution_isr_time_total[TX_THREAD_SMP_MAX_CORES];
-EXECUTION_TIME_SOURCE_TYPE _tx_execution_isr_time_last_start[TX_THREAD_SMP_MAX_CORES];
+EXECUTION_TIME_SOURCE_TYPE _tx_execution_isr_time_last_start[TX_THREAD_SMP_MAX_CORES];
/* Define the system idle time gathering information. For idle time that exceeds the range of the timer
- source, another timer source may be needed. In addition, the total thread execution time added to the
+ source, another timer source may be needed. In addition, the total thread execution time added to the
total ISR time, less the total system time is also a measure of idle time. */
EXECUTION_TIME _tx_execution_idle_time_total[TX_THREAD_SMP_MAX_CORES];
@@ -124,12 +125,6 @@ EXECUTION_TIME_SOURCE_TYPE _tx_execution_idle_time_last_start[TX_THREAD
/* */
/* _tx_thread_schedule Thread scheduling */
/* */
-/* RELEASE HISTORY */
-/* */
-/* DATE NAME DESCRIPTION */
-/* */
-/* 07-29-2022 William E. Lamie Initial Version 6.1.12 */
-/* */
/**************************************************************************/
VOID _tx_execution_thread_enter(void)
{
@@ -155,10 +150,10 @@ UINT core;
/* This thread is being scheduled. Simply setup the last start time in the
thread control block. */
thread_ptr -> tx_thread_execution_time_last_start = current_time;
-
+
/* Pickup the last idle start time. */
last_start_time = _tx_execution_idle_time_last_start[core];
-
+
/* Determine if idle time is being measured. */
if (last_start_time)
{
@@ -166,34 +161,34 @@ UINT core;
/* Determine how to calculate the difference. */
if (current_time >= last_start_time)
{
-
+
/* Simply subtract. */
delta_time = (EXECUTION_TIME) (current_time - last_start_time);
- }
+ }
else
{
-
+
/* Timer wrapped, compute the delta assuming incrementing time counter. */
delta_time = (EXECUTION_TIME) (current_time + (((EXECUTION_TIME_SOURCE_TYPE) TX_EXECUTION_MAX_TIME_SOURCE) - last_start_time));
}
-
+
/* Pickup the total time. */
total_time = _tx_execution_idle_time_total[core];
/* Now compute the new total time. */
new_total_time = total_time + delta_time;
-
+
/* Determine if a rollover on the total time is present. */
if (new_total_time < total_time)
{
-
+
/* Rollover. Set the total time to max value. */
new_total_time = (EXECUTION_TIME) TX_EXECUTION_MAX_TIME_SOURCE;
}
-
+
/* Now store back the total idle time. */
- _tx_execution_idle_time_total[core] = new_total_time;
-
+ _tx_execution_idle_time_total[core] = new_total_time;
+
/* Disable the idle time measurement. */
_tx_execution_idle_time_last_start[core] = 0;
}
@@ -258,7 +253,7 @@ UINT core;
/* Determine if there is a thread. */
if (thread_ptr)
{
-
+
/* Pickup the current time. */
current_time = TX_EXECUTION_TIME_SOURCE;
@@ -271,17 +266,17 @@ UINT core;
/* Clear the last start time. */
thread_ptr -> tx_thread_execution_time_last_start = 0;
-
+
/* Determine how to calculate the difference. */
if (current_time >= last_start_time)
{
-
+
/* Simply subtract. */
delta_time = (EXECUTION_TIME) (current_time - last_start_time);
- }
+ }
else
{
-
+
/* Timer wrapped, compute the delta assuming incrementing time counter. */
delta_time = (EXECUTION_TIME) (current_time + (((EXECUTION_TIME_SOURCE_TYPE) TX_EXECUTION_MAX_TIME_SOURCE) - last_start_time));
}
@@ -291,37 +286,37 @@ UINT core;
/* Now compute the new total time. */
new_total_time = total_time + delta_time;
-
+
/* Determine if a rollover on the total time is present. */
if (new_total_time < total_time)
{
-
+
/* Rollover. Set the total time to max value. */
new_total_time = (EXECUTION_TIME) TX_EXECUTION_MAX_TIME_SOURCE;
}
-
+
/* Store back the new total time. */
thread_ptr -> tx_thread_execution_time_total = new_total_time;
-
+
/* Now accumulate this thread's execution time into the total thread execution time. */
new_total_time = _tx_execution_thread_time_total[core] + delta_time;
-
+
/* Determine if a rollover on the total time is present. */
if (new_total_time < _tx_execution_thread_time_total[core])
{
-
+
/* Rollover. Set the total time to max value. */
new_total_time = (EXECUTION_TIME) TX_EXECUTION_MAX_TIME_SOURCE;
- }
+ }
/* Store back the new total time. */
_tx_execution_thread_time_total[core] = new_total_time;
}
-
+
/* Is the system now idle? */
if (_tx_thread_execute_ptr[core] == TX_NULL)
{
-
+
/* Yes, idle system. Pickup the start of idle time. */
_tx_execution_idle_time_last_start[core] = TX_EXECUTION_TIME_SOURCE;
}
@@ -381,7 +376,7 @@ UINT core;
/* Pickup the core index. */
core = TX_SMP_CORE_ID;
- /* Determine if this is the first interrupt. Nested interrupts are all treated as
+ /* Determine if this is the first interrupt. Nested interrupts are all treated as
general interrupt processing. */
if (_tx_thread_system_state[core] == 1)
{
@@ -394,7 +389,7 @@ UINT core;
/* Determine if a thread was interrupted. */
if (thread_ptr)
{
-
+
/* Pickup the last start time. */
last_start_time = thread_ptr -> tx_thread_execution_time_last_start;
@@ -404,17 +399,17 @@ UINT core;
/* Clear the last start time. */
thread_ptr -> tx_thread_execution_time_last_start = 0;
-
+
/* Determine how to calculate the difference. */
if (current_time >= last_start_time)
{
-
+
/* Simply subtract. */
delta_time = (EXECUTION_TIME) (current_time - last_start_time);
- }
+ }
else
{
-
+
/* Timer wrapped, compute the delta assuming incrementing time counter. */
delta_time = (EXECUTION_TIME) (current_time + (((EXECUTION_TIME_SOURCE_TYPE) TX_EXECUTION_MAX_TIME_SOURCE) - last_start_time));
}
@@ -424,72 +419,72 @@ UINT core;
/* Now compute the new total time. */
new_total_time = total_time + delta_time;
-
+
/* Determine if a rollover on the total time is present. */
if (new_total_time < total_time)
{
-
+
/* Rollover. Set the total time to max value. */
new_total_time = (EXECUTION_TIME) TX_EXECUTION_MAX_TIME_SOURCE;
}
-
+
/* Store back the new total time. */
thread_ptr -> tx_thread_execution_time_total = new_total_time;
/* Now accumulate this thread's execution time into the total thread execution time. */
new_total_time = _tx_execution_thread_time_total[core] + delta_time;
-
+
/* Determine if a rollover on the total time is present. */
if (new_total_time < _tx_execution_thread_time_total[core])
{
-
+
/* Rollover. Set the total time to max value. */
new_total_time = (EXECUTION_TIME) TX_EXECUTION_MAX_TIME_SOURCE;
- }
+ }
/* Store back the new total time. */
_tx_execution_thread_time_total[core] = new_total_time;
}
}
-
+
/* Has idle time started? */
else if (_tx_execution_idle_time_last_start[core])
{
-
+
/* Pickup the last idle start time. */
last_start_time = _tx_execution_idle_time_last_start[core];
-
+
/* Determine how to calculate the difference. */
if (current_time >= last_start_time)
{
-
+
/* Simply subtract. */
delta_time = (EXECUTION_TIME) (current_time - last_start_time);
- }
+ }
else
{
-
+
/* Timer wrapped, compute the delta assuming incrementing time counter. */
delta_time = (EXECUTION_TIME) (current_time + (((EXECUTION_TIME_SOURCE_TYPE) TX_EXECUTION_MAX_TIME_SOURCE) - last_start_time));
}
-
+
/* Pickup the total time. */
total_time = _tx_execution_idle_time_total[core];
/* Now compute the new total time. */
new_total_time = total_time + delta_time;
-
+
/* Determine if a rollover on the total time is present. */
if (new_total_time < total_time)
{
-
+
/* Rollover. Set the total time to max value. */
new_total_time = (EXECUTION_TIME) TX_EXECUTION_MAX_TIME_SOURCE;
}
-
+
/* Now store back the total idle time. */
- _tx_execution_idle_time_total[core] = new_total_time;
-
+ _tx_execution_idle_time_total[core] = new_total_time;
+
/* Disable the idle time measurement. */
_tx_execution_idle_time_last_start[core] = 0;
}
@@ -552,7 +547,7 @@ UINT core;
/* Pickup the core index. */
core = TX_SMP_CORE_ID;
- /* Determine if this is the first interrupt. Nested interrupts are all treated as
+ /* Determine if this is the first interrupt. Nested interrupts are all treated as
general interrupt processing. */
if (_tx_thread_system_state[core] == 1)
{
@@ -562,17 +557,17 @@ UINT core;
/* Pickup the last start time. */
last_start_time = _tx_execution_isr_time_last_start[core];
-
+
/* Determine how to calculate the difference. */
if (current_time >= last_start_time)
{
-
+
/* Simply subtract. */
delta_time = (EXECUTION_TIME) (current_time - last_start_time);
}
else
{
-
+
/* Timer wrapped, compute the delta assuming incrementing time counter. */
delta_time = (EXECUTION_TIME) (current_time + (((EXECUTION_TIME_SOURCE_TYPE) TX_EXECUTION_MAX_TIME_SOURCE) - last_start_time));
}
@@ -582,18 +577,18 @@ UINT core;
/* Now compute the new total time. */
new_total_time = total_time + delta_time;
-
+
/* Determine if a rollover on the total time is present. */
if (new_total_time < total_time)
{
-
+
/* Rollover. Set the total time to max value. */
new_total_time = (EXECUTION_TIME) TX_EXECUTION_MAX_TIME_SOURCE;
}
-
+
/* Store back the new total time. */
_tx_execution_isr_time_total[core] = new_total_time;
-
+
/* Pickup the current thread control block. */
thread_ptr = _tx_thread_current_ptr[core];
@@ -604,16 +599,16 @@ UINT core;
/* Now determine if the thread will execution is going to occur immediately. */
if ((thread_ptr == _tx_thread_execute_ptr[core]) || (_tx_thread_preempt_disable))
{
-
+
/* Yes, setup the thread last start time in the thread control block. */
thread_ptr -> tx_thread_execution_time_last_start = current_time;
}
}
-
+
/* Determine if the system is now idle. */
if (_tx_thread_execute_ptr[core] == TX_NULL)
{
-
+
/* Yes, idle system. Pickup the start of idle time. */
_tx_execution_idle_time_last_start[core] = TX_EXECUTION_TIME_SOURCE;
}
@@ -710,8 +705,8 @@ UINT _tx_execution_thread_total_time_reset(void)
{
TX_INTERRUPT_SAVE_AREA
-
-TX_THREAD *thread_ptr;
+
+TX_THREAD *thread_ptr;
UINT total_threads;
UINT core;
@@ -722,7 +717,7 @@ UINT core;
/* Reset the total time for all cores. */
for (core = 0; core < TX_THREAD_SMP_MAX_CORES; core++)
{
-
+
_tx_execution_thread_time_total[core] = 0;
}
@@ -799,7 +794,7 @@ UINT core;
/* Restore interrupts. */
TX_RESTORE
-
+
/* Return success. */
return(TX_SUCCESS);
}
@@ -969,10 +964,10 @@ UINT core;
*total_time = _tx_execution_thread_time_total[core];
}
-
+
/* Restore interrupts. */
TX_RESTORE
-
+
/* Return success. */
return(TX_SUCCESS);
}
@@ -1032,7 +1027,7 @@ UINT core;
/* Return the total time. */
*total_time = _tx_execution_isr_time_total[core];
}
-
+
/* Restore interrupts. */
TX_RESTORE
@@ -1149,14 +1144,14 @@ UINT _tx_execution_core_thread_total_time_get(UINT core, EXECUTION_TIME *total_
/* Determine if the core is valid. */
if (core >= TX_THREAD_SMP_MAX_CORES)
{
-
+
/* Invalid core, return an error. */
return(TX_NOT_DONE);
}
/* Return the total thread time for the core. */
*total_time = _tx_execution_thread_time_total[core];
-
+
/* Return success. */
return(TX_SUCCESS);
}
@@ -1207,7 +1202,7 @@ UINT _tx_execution_core_isr_time_get(UINT core, EXECUTION_TIME *total_time)
/* Determine if the core is valid. */
if (core >= TX_THREAD_SMP_MAX_CORES)
{
-
+
/* Invalid core, return an error. */
return(TX_NOT_DONE);
}
@@ -1264,7 +1259,7 @@ UINT _tx_execution_core_idle_time_get(UINT core, EXECUTION_TIME *total_time)
/* Determine if the core is valid. */
if (core >= TX_THREAD_SMP_MAX_CORES)
{
-
+
/* Invalid core, return an error. */
return(TX_NOT_DONE);
}
diff --git a/utility/execution_profile_kit/smp_version/tx_execution_profile.h b/utility/execution_profile_kit/smp_version/tx_execution_profile.h
index 1d1ac587..fee0e17c 100644
--- a/utility/execution_profile_kit/smp_version/tx_execution_profile.h
+++ b/utility/execution_profile_kit/smp_version/tx_execution_profile.h
@@ -1,10 +1,11 @@
/***************************************************************************
- * Copyright (c) 2024 Microsoft Corporation
- *
+ * Copyright (c) 2024 Microsoft Corporation
+ * Copyright (c) 2026-present Eclipse ThreadX contributors
+ *
* This program and the accompanying materials are made available under the
* terms of the MIT License which is available at
* https://opensource.org/licenses/MIT.
- *
+ *
* SPDX-License-Identifier: MIT
**************************************************************************/
@@ -24,20 +25,20 @@
#define TX_EXECUTION_PROFILE_H
-/* The thread execution profile kit is designed to track thread execution time
- based on the hardware timer defined by TX_EXECUTION_TIME_SOURCE and
- TX_EXECUTION_MAX_TIME_SOURCE below. When the thread's total time reaches
+/* The thread execution profile kit is designed to track thread execution time
+ based on the hardware timer defined by TX_EXECUTION_TIME_SOURCE and
+ TX_EXECUTION_MAX_TIME_SOURCE below. When the thread's total time reaches
the maximum value, it remains there until the time is reset to 0 via a call
- to tx_thread_execution_time_reset. There are several assumptions to the
+ to tx_thread_execution_time_reset. There are several assumptions to the
operation of this kit, as follows:
1. In tx_port.h replace:
#define TX_THREAD_EXTENSION_3"
with:
#define TX_THREAD_EXTENSION_3 unsigned long long tx_thread_execution_time_total; \
- unsigned long tx_thread_execution_time_last_start;
+ unsigned long tx_thread_execution_time_last_start;
- 2. The TX_EXECUTION_TIME_SOURCE and TX_EXECUTION_MAX_TIME_SOURCE macros are
+ 2. The TX_EXECUTION_TIME_SOURCE and TX_EXECUTION_MAX_TIME_SOURCE macros are
defined to utilize a local hardware time source.
3. The following routines are called from assembly code:
@@ -46,9 +47,9 @@
VOID _tx_execution_isr_enter(void);
VOID _tx_execution_isr_exit(void);
- 4. The ThreadX library must be rebuilt with TX_ENABLE_EXECUTION_CHANGE_NOTIFY so
- that these macros are expanded in the TX_THREAD structure and so the assembly code macros
- are enabled to call the execution profile routines.
+ 4. The ThreadX library must be rebuilt with TX_ENABLE_EXECUTION_CHANGE_NOTIFY so
+ that these macros are expanded in the TX_THREAD structure and so the assembly code macros
+ are enabled to call the execution profile routines.
5. Add tx_execution_profile.c to the application build. */