diff --git a/doc/services/debugging/thread-analyzer.rst b/doc/services/debugging/thread-analyzer.rst index 57e433ff176c4..d6ff834d07c0f 100644 --- a/doc/services/debugging/thread-analyzer.rst +++ b/doc/services/debugging/thread-analyzer.rst @@ -86,6 +86,12 @@ Configure this module using the following options. :kconfig:option:`CONFIG_THREAD_RUNTIME_STATS` Print thread runtime data such as utilization. This options is automatically selected by :kconfig:option:`CONFIG_THREAD_ANALYZER`. +:kconfig:option:`CONFIG_THREAD_ANALYZER_LONG_FRAME_PER_INTERVAL` + Reset Longest Frame value statistics after printing. + When using :kconfig:option:`SCHED_THREAD_USAGE_ANALYSIS` to get average and longest + frame thread statistics, reset the Longest Frame value to zero after each time + printing the thread statistics. This enables observation of the longest frame + during the most recent interval rather than longest frame since startup. API documentation ***************** diff --git a/include/zephyr/kernel.h b/include/zephyr/kernel.h index 687d88368935e..3dd4b7c589ea8 100644 --- a/include/zephyr/kernel.h +++ b/include/zephyr/kernel.h @@ -103,6 +103,27 @@ typedef int (*_poller_cb_t)(struct k_poll_event *event, uint32_t state); * @{ */ +/** + * @brief Resets thread longest frame usage data for specified thread + * + * This routine resets the longest frame value statistic + * after printing to zero, enabling observation of the + * longest frame from the most recent interval rather than + * the longest frame since startup. + * + * @param thread Pointer to the thread to reset counter. + * + * @note @kconfig{CONFIG_THREAD_ANALYZER_LONG_FRAME_PER_INTERVAL} must + * be set for this function to be effective. + */ +static inline void + k_thread_runtime_stats_longest_frame_reset(__maybe_unused struct k_thread *thread) +{ +#ifdef CONFIG_SCHED_THREAD_USAGE_ANALYSIS + thread->base.usage.longest = 0ULL; +#endif +} + typedef void (*k_thread_user_cb_t)(const struct k_thread *thread, void *user_data); diff --git a/subsys/debug/thread_analyzer/Kconfig b/subsys/debug/thread_analyzer/Kconfig index d0828a3b64239..a3937ade25edd 100644 --- a/subsys/debug/thread_analyzer/Kconfig +++ b/subsys/debug/thread_analyzer/Kconfig @@ -113,4 +113,12 @@ endif # THREAD_ANALYZER_AUTO_THREAD_PRIORITY_OVERRIDE endif # THREAD_ANALYZER_AUTO +config THREAD_ANALYZER_LONG_FRAME_PER_INTERVAL + bool "Prints the longest frame since the last thread analyzer interval" + depends on SCHED_THREAD_USAGE_ANALYSIS + help + Resets the thread longest frame field after printing so that the next print + will show the longest frame during that interval. This enables observation + of what long frames come after the initial startup of a thread. + endif # THREAD_ANALYZER diff --git a/subsys/debug/thread_analyzer/thread_analyzer.c b/subsys/debug/thread_analyzer/thread_analyzer.c index a35d9a386c413..360b79ed53387 100644 --- a/subsys/debug/thread_analyzer/thread_analyzer.c +++ b/subsys/debug/thread_analyzer/thread_analyzer.c @@ -170,6 +170,11 @@ static void thread_analyze_cb(const struct k_thread *cthread, void *user_data) ARG_UNUSED(ret); cb(&info); + +#if IS_ENABLED(CONFIG_THREAD_ANALYZER_LONG_FRAME_PER_INTERVAL) + k_thread_runtime_stats_longest_frame_reset(thread); +#endif + } K_KERNEL_STACK_ARRAY_DECLARE(z_interrupt_stacks, CONFIG_MP_MAX_NUM_CPUS,