[Add][kservice]Add thread usage support.

This commit is contained in:
Rbb666
2025-08-28 19:10:16 +08:00
committed by R b b666
parent 1e34830f6d
commit bc4c036942
4 changed files with 74 additions and 7 deletions

View File

@@ -165,6 +165,7 @@ long list_thread(void)
rt_list_t *next = (rt_list_t *)RT_NULL; rt_list_t *next = (rt_list_t *)RT_NULL;
const char *item_title = "thread"; const char *item_title = "thread";
const size_t tcb_strlen = sizeof(void *) * 2 + 2; const size_t tcb_strlen = sizeof(void *) * 2 + 2;
const size_t usage_strlen = sizeof(void *) + 1;
int maxlen; int maxlen;
list_find_init(&find_arg, RT_Object_Class_Thread, obj_list, sizeof(obj_list) / sizeof(obj_list[0])); list_find_init(&find_arg, RT_Object_Class_Thread, obj_list, sizeof(obj_list) / sizeof(obj_list[0]));
@@ -173,18 +174,22 @@ long list_thread(void)
maxlen = RT_NAME_MAX; maxlen = RT_NAME_MAX;
#ifdef RT_USING_SMP #ifdef RT_USING_SMP
rt_kprintf("%-*.*s cpu bind pri status sp stack size max used left tick error tcb addr\n", maxlen, maxlen, item_title); rt_kprintf("%-*.*s cpu bind pri status sp stack size max used left tick error tcb addr usage\n", maxlen, maxlen, item_title);
object_split(maxlen); object_split(maxlen);
rt_kprintf(" --- ---- --- ------- ---------- ---------- ------ ---------- -------"); rt_kprintf(" --- ---- --- ------- ---------- ---------- ------ ---------- -------");
rt_kprintf(" "); rt_kprintf(" ");
object_split(tcb_strlen); object_split(tcb_strlen);
rt_kprintf(" ");
object_split(usage_strlen);
rt_kprintf("\n"); rt_kprintf("\n");
#else #else
rt_kprintf("%-*.*s pri status sp stack size max used left tick error tcb addr\n", maxlen, maxlen, item_title); rt_kprintf("%-*.*s pri status sp stack size max used left tick error tcb addr usage\n", maxlen, maxlen, item_title);
object_split(maxlen); object_split(maxlen);
rt_kprintf(" --- ------- ---------- ---------- ------ ---------- -------"); rt_kprintf(" --- ------- ---------- ---------- ------ ---------- -------");
rt_kprintf(" "); rt_kprintf(" ");
object_split(tcb_strlen); object_split(tcb_strlen);
rt_kprintf(" ");
object_split(usage_strlen);
rt_kprintf("\n"); rt_kprintf("\n");
#endif /*RT_USING_SMP*/ #endif /*RT_USING_SMP*/
@@ -243,17 +248,22 @@ long list_thread(void)
ptr = (rt_uint8_t *)thread->stack_addr + thread->stack_size - 1; ptr = (rt_uint8_t *)thread->stack_addr + thread->stack_size - 1;
while (*ptr == '#')ptr --; while (*ptr == '#')ptr --;
rt_kprintf(" 0x%08x 0x%08x %02d%% 0x%08x %s %p\n", rt_kprintf(" 0x%08x 0x%08x %02d%% 0x%08x %s %p",
((rt_ubase_t)thread->sp - (rt_ubase_t)thread->stack_addr), ((rt_ubase_t)thread->sp - (rt_ubase_t)thread->stack_addr),
thread->stack_size, thread->stack_size,
((rt_ubase_t)ptr - (rt_ubase_t)thread->stack_addr) * 100 / thread->stack_size, ((rt_ubase_t)ptr - (rt_ubase_t)thread->stack_addr) * 100 / thread->stack_size,
thread->remaining_tick, thread->remaining_tick,
rt_strerror(thread->error), rt_strerror(thread->error),
thread); thread);
#ifdef RT_USING_CPU_USAGE_TRACER
rt_kprintf(" %3d%%\n", rt_thread_get_usage(thread));
#else
rt_kprintf(" N/A\n");
#endif
#else #else
ptr = (rt_uint8_t *)thread->stack_addr; ptr = (rt_uint8_t *)thread->stack_addr;
while (*ptr == '#') ptr ++; while (*ptr == '#') ptr ++;
rt_kprintf(" 0x%08x 0x%08x %02d%% 0x%08x %s %p\n", rt_kprintf(" 0x%08x 0x%08x %02d%% 0x%08x %s %p",
thread->stack_size + ((rt_ubase_t)thread->stack_addr - (rt_ubase_t)thread->sp), thread->stack_size + ((rt_ubase_t)thread->stack_addr - (rt_ubase_t)thread->sp),
thread->stack_size, thread->stack_size,
(thread->stack_size - ((rt_ubase_t) ptr - (rt_ubase_t) thread->stack_addr)) * 100 (thread->stack_size - ((rt_ubase_t) ptr - (rt_ubase_t) thread->stack_addr)) * 100
@@ -261,6 +271,11 @@ long list_thread(void)
RT_SCHED_PRIV(thread).remaining_tick, RT_SCHED_PRIV(thread).remaining_tick,
rt_strerror(thread->error), rt_strerror(thread->error),
thread); thread);
#ifdef RT_USING_CPU_USAGE_TRACER
rt_kprintf(" %3d%%\n", rt_thread_get_usage(thread));
#else
rt_kprintf(" N/A\n");
#endif
#endif #endif
} }
} }

View File

@@ -181,6 +181,9 @@ rt_err_t rt_thread_wakeup(rt_thread_t thread);
void rt_thread_wakeup_set(struct rt_thread *thread, rt_wakeup_func_t func, void* user_data); void rt_thread_wakeup_set(struct rt_thread *thread, rt_wakeup_func_t func, void* user_data);
#endif /* RT_USING_SMART */ #endif /* RT_USING_SMART */
rt_err_t rt_thread_get_name(rt_thread_t thread, char *name, rt_uint8_t name_size); rt_err_t rt_thread_get_name(rt_thread_t thread, char *name, rt_uint8_t name_size);
#ifdef RT_USING_CPU_USAGE_TRACER
rt_uint8_t rt_thread_get_usage(rt_thread_t thread);
#endif /* RT_USING_CPU_USAGE_TRACER */
#ifdef RT_USING_SIGNALS #ifdef RT_USING_SIGNALS
void rt_thread_alloc_sig(rt_thread_t tid); void rt_thread_alloc_sig(rt_thread_t tid);
void rt_thread_free_sig(rt_thread_t tid); void rt_thread_free_sig(rt_thread_t tid);

View File

@@ -192,10 +192,12 @@ endif
config RT_USING_CPU_USAGE_TRACER config RT_USING_CPU_USAGE_TRACER
select RT_USING_HOOK select RT_USING_HOOK
bool "Enable cpu usage tracing" bool "Enable cpu usage tracing"
help
Enable cpu usage tracer for application like top.
default y if RT_USING_SMART
default n default n
help
Enable thread CPU usage statistics and monitoring.
This feature tracks CPU usage for each thread and provides
percentage information through the list thread command.
It will automatically integrate with the scheduler to track thread execution time.
menu "kservice options" menu "kservice options"
config RT_USING_TINY_FFS config RT_USING_TINY_FFS

View File

@@ -535,6 +535,53 @@ rt_err_t rt_backtrace_thread(rt_thread_t thread)
return rc; return rc;
} }
#ifdef RT_USING_CPU_USAGE_TRACER
/**
* @brief Get thread usage percentage relative to total system CPU time
*
* This function calculates the CPU usage percentage of a specific thread
* relative to the total CPU time consumed by all threads in the system.
*
* @param thread Pointer to the thread object. Must not be NULL.
*
* @return The CPU usage percentage as an integer value (0-100).
* Returns 0 if total system time is 0 or if CPU usage tracing is not enabled.
*
* @note This function requires RT_USING_CPU_USAGE_TRACER to be enabled.
* @note The percentage is calculated as: (thread_time * 100) / total_system_time
* @note Due to integer arithmetic, the result is truncated and may not sum
* to exactly 100% across all threads due to rounding.
* @note If thread is NULL, an assertion will be triggered in debug builds.
*/
rt_uint8_t rt_thread_get_usage(rt_thread_t thread)
{
rt_ubase_t thread_time;
rt_ubase_t total_time = 0U;
int i;
rt_cpu_t pcpu;
RT_ASSERT(thread != RT_NULL);
thread_time = thread->user_time + thread->system_time;
/* Calculate total system time by summing all CPUs' time */
for (i = 0; i < RT_CPUS_NR; i++)
{
pcpu = rt_cpu_index(i);
total_time += pcpu->cpu_stat.user + pcpu->cpu_stat.system + pcpu->cpu_stat.idle;
}
if (total_time > 0U)
{
/* Calculate thread usage percentage: (thread_time * 100) / total_time */
rt_ubase_t usage = (thread_time * 100U) / total_time;
return (rt_uint8_t)(usage > 100U ? 100U : usage);
}
return 0U;
}
#endif /* RT_USING_CPU_USAGE_TRACER */
#if defined(RT_USING_LIBC) && defined(RT_USING_FINSH) #if defined(RT_USING_LIBC) && defined(RT_USING_FINSH)
#include <stdlib.h> /* for string service */ #include <stdlib.h> /* for string service */