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:
parent
7009012d67
commit
802d214582
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue