diff --git a/include/kernel.h b/include/kernel.h index 40c6830b7a..ba03eefd65 100644 --- a/include/kernel.h +++ b/include/kernel.h @@ -19,6 +19,10 @@ #include #include +#ifdef CONFIG_THREAD_RUNTIME_STATS_USE_TIMING_FUNCTIONS +#include +#endif + #ifdef __cplusplus extern "C" { #endif @@ -283,14 +287,22 @@ struct z_poller { #ifdef CONFIG_THREAD_RUNTIME_STATS struct k_thread_runtime_stats { /* Thread execution cycles */ +#ifdef CONFIG_THREAD_RUNTIME_STATS_USE_TIMING_FUNCTIONS + timing_t execution_cycles; +#else uint64_t execution_cycles; +#endif }; typedef struct k_thread_runtime_stats k_thread_runtime_stats_t; struct _thread_runtime_stats { /* Timestamp when last switched in */ +#ifdef CONFIG_THREAD_RUNTIME_STATS_USE_TIMING_FUNCTIONS + timing_t last_switched_in; +#else uint32_t last_switched_in; +#endif k_thread_runtime_stats_t stats; }; diff --git a/kernel/Kconfig b/kernel/Kconfig index 251cddab4d..e39067d701 100644 --- a/kernel/Kconfig +++ b/kernel/Kconfig @@ -355,7 +355,7 @@ config THREAD_MAX_NAME_LEN config INSTRUMENT_THREAD_SWITCHING bool -config THREAD_RUNTIME_STATS +menuconfig THREAD_RUNTIME_STATS bool "Thread runtime statistics" select INSTRUMENT_THREAD_SWITCHING help @@ -364,6 +364,19 @@ config THREAD_RUNTIME_STATS For example: - Thread total execution cycles +if THREAD_RUNTIME_STATS + +config THREAD_RUNTIME_STATS_USE_TIMING_FUNCTIONS + bool "Use timing functions to gather statistics" + select TIMING_FUNCTIONS + help + Use timing functions to gather thread runtime statistics. + + Note that timing functions may use a different timer than + the default timer for OS timekeeping. + +endif # THREAD_RUNTIME_STATS + endmenu menu "Work Queue Options" diff --git a/kernel/init.c b/kernel/init.c index 27c52aae12..38dde05b14 100644 --- a/kernel/init.c +++ b/kernel/init.c @@ -480,6 +480,11 @@ FUNC_NORETURN void z_cstart(void) __stack_chk_guard <<= 8; #endif /* CONFIG_STACK_CANARIES */ +#ifdef CONFIG_THREAD_RUNTIME_STATS_USE_TIMING_FUNCTIONS + timing_init(); + timing_start(); +#endif + #ifdef CONFIG_MULTITHREADING switch_to_main_thread(prepare_multithreading()); #else diff --git a/kernel/thread.c b/kernel/thread.c index ebc3c493fc..6a9760fe91 100644 --- a/kernel/thread.c +++ b/kernel/thread.c @@ -1036,14 +1036,24 @@ void z_thread_mark_switched_in(void) struct k_thread *thread; thread = k_current_get(); +#ifdef CONFIG_THREAD_RUNTIME_STATS_USE_TIMING_FUNCTIONS + thread->rt_stats.last_switched_in = timing_counter_get(); +#else thread->rt_stats.last_switched_in = k_cycle_get_32(); +#endif /* CONFIG_THREAD_RUNTIME_STATS_USE_TIMING_FUNCTIONS */ + #endif /* CONFIG_THREAD_RUNTIME_STATS */ } void z_thread_mark_switched_out(void) { #ifdef CONFIG_THREAD_RUNTIME_STATS +#ifdef CONFIG_THREAD_RUNTIME_STATS_USE_TIMING_FUNCTIONS + timing_t now; +#else uint32_t now; +#endif /* CONFIG_THREAD_RUNTIME_STATS_USE_TIMING_FUNCTIONS */ + uint64_t diff; struct k_thread *thread; @@ -1059,10 +1069,16 @@ void z_thread_mark_switched_out(void) return; } +#ifdef CONFIG_THREAD_RUNTIME_STATS_USE_TIMING_FUNCTIONS + now = timing_counter_get(); + diff = timing_cycles_get(&thread->rt_stats.last_switched_in, &now); +#else now = k_cycle_get_32(); diff = (uint64_t)now - thread->rt_stats.last_switched_in; - thread->rt_stats.stats.execution_cycles += diff; thread->rt_stats.last_switched_in = 0; +#endif /* CONFIG_THREAD_RUNTIME_STATS_USE_TIMING_FUNCTIONS */ + + thread->rt_stats.stats.execution_cycles += diff; threads_runtime_stats.execution_cycles += diff; #endif /* CONFIG_THREAD_RUNTIME_STATS */