debug: analyzer: add support for thread runtime stats

Add thread runtime statistics to the thread analyser.

With CONFIG_THREAD_RUNTIME_STATS enabled:

Booting from ROM..*** Booting Zephyr OS build zephyr-v2.4.0-2330-g77be0e93e65b  ***
thread_a: Hello World from cpu 0 on qemu_x86!
Thread analyze:
 thread_b            : STACK: unused 740 usage 284 / 1024 (27 %); CPU: 0 %
 thread_analyzer     : STACK: unused 8 usage 504 / 512 (98 %); CPU: 0 %
 thread_a            : STACK: unused 648 usage 376 / 1024 (36 %); CPU: 98 %
 idle 00             : STACK: unused 204 usage 116 / 320 (36 %); CPU: 0 %
thread_b: Hello World from cpu 0 on qemu_x86!
thread_a: Hello World from cpu 0 on qemu_x86!
thread_b: Hello World from cpu 0 on qemu_x86!
thread_a: Hello World from cpu 0 on qemu_x86!
thread_b: Hello World from cpu 0 on qemu_x86!
thread_a: Hello World from cpu 0 on qemu_x86!
thread_b: Hello World from cpu 0 on qemu_x86!
thread_a: Hello World from cpu 0 on qemu_x86!
Thread analyze:
 thread_b            : STACK: unused 648 usage 376 / 1024 (36 %); CPU: 7 %
 thread_analyzer     : STACK: unused 8 usage 504 / 512 (98 %); CPU: 0 %
 thread_a            : STACK: unused 648 usage 376 / 1024 (36 %); CPU: 9 %
 idle 00             : STACK: unused 204 usage 116 / 320 (36 %); CPU: 82 %
thread_b: Hello World from cpu 0 on qemu_x86!

Signed-off-by: Anas Nashif <anas.nashif@intel.com>
This commit is contained in:
Anas Nashif 2020-12-12 08:41:27 -05:00
parent 7009012d67
commit 802d214582
4 changed files with 39 additions and 1 deletions

View file

@ -29,6 +29,10 @@ struct thread_analyzer_info {
size_t stack_size;
/** Stack size in used */
size_t stack_used;
#ifdef CONFIG_THREAD_RUNTIME_STATS
unsigned int utilization;
#endif
};
/** @brief Thread analyzer stack size callback function

View file

@ -60,6 +60,7 @@ void helloLoop(const char *my_name,
}
/* wait a while, then let other thread have a turn */
k_busy_wait(100000);
k_msleep(SLEEPTIME);
k_sem_give(other_sem);
}

View file

@ -17,6 +17,7 @@ menuconfig THREAD_ANALYZER
select INIT_STACKS
select THREAD_MONITOR
select THREAD_STACK_INFO
select THREAD_RUNTIME_STATS
help
Enable thread analyzer functionality and all the required modules.
This module may be used to debug thread configuration issues, e.g.

View file

@ -38,18 +38,32 @@ LOG_MODULE_REGISTER(thread_analyzer, CONFIG_THREAD_ANALYZER_LOG_LEVEL);
static void thread_print_cb(struct thread_analyzer_info *info)
{
unsigned int pcnt = (info->stack_used * 100U) / info->stack_size;
#ifdef CONFIG_THREAD_RUNTIME_STATS
THREAD_ANALYZER_PRINT(
THREAD_ANALYZER_FMT(
" %-20s: STACK: unused %zu usage %zu / %zu (%zu %%); CPU: %zu %%"),
THREAD_ANALYZER_VSTR(info->name),
info->stack_size - info->stack_used, info->stack_used,
info->stack_size, pcnt,
info->utilization);
#else
THREAD_ANALYZER_PRINT(
THREAD_ANALYZER_FMT(
" %-20s: unused %zu usage %zu / %zu (%zu %%)"),
THREAD_ANALYZER_VSTR(info->name),
info->stack_size - info->stack_used, info->stack_used,
info->stack_size, pcnt);
#endif
}
static void thread_analyze_cb(const struct k_thread *cthread, void *user_data)
{
struct k_thread *thread = (struct k_thread *)cthread;
#ifdef CONFIG_THREAD_RUNTIME_STATS
k_thread_runtime_stats_t rt_stats_all;
k_thread_runtime_stats_t rt_stats_thread;
int ret;
#endif
size_t size = thread->stack_info.size;
thread_analyzer_cb cb = user_data;
struct thread_analyzer_info info;
@ -58,6 +72,8 @@ static void thread_analyze_cb(const struct k_thread *cthread, void *user_data)
size_t unused;
int err;
name = k_thread_name_get((k_tid_t)thread);
if (!name || name[0] == '\0') {
name = hexname;
@ -77,6 +93,22 @@ static void thread_analyze_cb(const struct k_thread *cthread, void *user_data)
info.name = name;
info.stack_size = size;
info.stack_used = size - unused;
#ifdef CONFIG_THREAD_RUNTIME_STATS
ret = 0;
if (k_thread_runtime_stats_get(thread, &rt_stats_thread) != 0) {
ret++;
};
if (k_thread_runtime_stats_all_get(&rt_stats_all) != 0) {
ret++;
}
if (ret == 0) {
info.utilization = (rt_stats_thread.execution_cycles * 100U) /
rt_stats_all.execution_cycles;
}
#endif
cb(&info);
}