mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2025-11-16 12:34:33 +00:00
[Add][kservice]Add thread usage support.
This commit is contained in:
@@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user