[smart] add CPU/thread usage tracing config (#8947)

* [smart] add CPU usage tracing config

This patch introduces following features:

- Added CPU usage tracing functionality, enabled by default, for
  applications like 'top'
- update time as smart independent

Signed-off-by: Shell <smokewood@qq.com>

* fixup: add ump idle thread

---------

Signed-off-by: Shell <smokewood@qq.com>
This commit is contained in:
Shell 2024-06-04 00:06:41 +08:00 committed by GitHub
parent e03342ff6b
commit 6ca327d8ce
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 77 additions and 53 deletions

View File

@ -686,37 +686,3 @@ rt_err_t lwp_backtrace_frame(rt_thread_t uthread, struct rt_hw_backtrace_frame *
}
return rc;
}
void rt_update_process_times(void)
{
struct rt_thread *thread;
#ifdef RT_USING_SMP
struct rt_cpu* pcpu;
pcpu = rt_cpu_self();
#endif
thread = rt_thread_self();
if (!IS_USER_MODE(thread))
{
thread->user_time += 1;
#ifdef RT_USING_SMP
pcpu->cpu_stat.user += 1;
#endif
}
else
{
thread->system_time += 1;
#ifdef RT_USING_SMP
if (thread == pcpu->idle_thread)
{
pcpu->cpu_stat.idle += 1;
}
else
{
pcpu->cpu_stat.system += 1;
}
#endif
}
}

View File

@ -701,6 +701,18 @@ enum
#define RT_THREAD_CTRL_INFO 0x03 /**< Get thread information. */
#define RT_THREAD_CTRL_BIND_CPU 0x04 /**< Set thread bind cpu. */
/**
* CPU usage statistics data
*/
struct rt_cpu_usage_stats
{
rt_ubase_t user;
rt_ubase_t system;
rt_ubase_t irq;
rt_ubase_t idle;
};
typedef struct rt_cpu_usage_stats *rt_cpu_usage_stats_t;
#ifdef RT_USING_SMP
#define RT_CPU_DETACHED RT_CPUS_NR /**< The thread not running on cpu. */
@ -714,15 +726,6 @@ enum
#define RT_STOP_IPI 1
#endif /* RT_STOP_IPI */
struct rt_cpu_usage_stats
{
rt_uint64_t user;
rt_uint64_t system;
rt_uint64_t irq;
rt_uint64_t idle;
};
typedef struct rt_cpu_usage_stats *rt_cpu_usage_stats_t;
#define _SCHEDULER_CONTEXT(fileds) fileds
/**
@ -762,14 +765,21 @@ struct rt_cpu
#ifdef RT_USING_SMART
struct rt_spinlock spinlock;
#endif /* RT_USING_SMART */
#ifdef RT_USING_CPU_USAGE_TRACER
struct rt_cpu_usage_stats cpu_stat;
#endif
#endif /* RT_USING_CPU_USAGE_TRACER */
};
#else /* !RT_USING_SMP */
struct rt_cpu
{
struct rt_thread *current_thread;
struct rt_thread *idle_thread;
#ifdef RT_USING_CPU_USAGE_TRACER
struct rt_cpu_usage_stats cpu_stat;
#endif /* RT_USING_CPU_USAGE_TRACER */
};
#endif /* RT_USING_SMP */
@ -947,9 +957,6 @@ struct rt_thread
void *susp_recycler; /**< suspended recycler on this thread */
void *robust_list; /**< pi lock, very carefully, it's a userspace list!*/
rt_uint64_t user_time;
rt_uint64_t system_time;
#ifndef ARCH_MM_MMU
lwp_sighandler_t signal_handler[32];
#else
@ -963,6 +970,11 @@ struct rt_thread
#endif /* ARCH_MM_MMU */
#endif /* RT_USING_SMART */
#ifdef RT_USING_CPU_USAGE_TRACER
rt_ubase_t user_time; /**< Ticks on user */
rt_ubase_t system_time; /**< Ticks on system */
#endif /* RT_USING_CPU_USAGE_TRACER */
#ifdef RT_USING_MEM_PROTECTION
void *mem_regions;
#ifdef RT_USING_HW_STACK_GUARD
@ -976,7 +988,9 @@ struct rt_thread
typedef struct rt_thread *rt_thread_t;
#ifdef RT_USING_SMART
#define IS_USER_MODE(t) ((t)->user_ctx.ctx == RT_NULL)
#define LWP_IS_USER_MODE(t) ((t)->user_ctx.ctx == RT_NULL)
#else
#define LWP_IS_USER_MODE(t) (0)
#endif /* RT_USING_SMART */
/**@}*/

View File

@ -183,6 +183,14 @@ if RT_USING_TIMER_SOFT
default 512
endif
config RT_USING_CPU_USAGE_TRACER
select RT_USING_HOOK
bool "Enable cpu usage tracing"
help
Enable cpu usage tracer for application like top.
default y if RT_USING_SMART
default n
menu "kservice optimization"
config RT_USING_TINY_FFS
bool "Enable kservice to use tiny finding first bit set method"

View File

@ -79,6 +79,36 @@ void rt_tick_set(rt_tick_t tick)
rt_atomic_store(&(rt_tick), tick);
}
#ifdef RT_USING_CPU_USAGE_TRACER
static void _update_process_times(void)
{
struct rt_thread *thread = rt_thread_self();
struct rt_cpu *pcpu = rt_cpu_self();
if (!LWP_IS_USER_MODE(thread))
{
thread->user_time += 1;
pcpu->cpu_stat.user += 1;
}
else
{
thread->system_time += 1;
if (thread == pcpu->idle_thread)
{
pcpu->cpu_stat.idle += 1;
}
else
{
pcpu->cpu_stat.system += 1;
}
}
}
#else
#define _update_process_times()
#endif /* RT_USING_CPU_USAGE_TRACER */
/**
* @brief This function will notify kernel there is one tick passed.
* Normally, this function is invoked by clock ISR.
@ -88,6 +118,10 @@ void rt_tick_increase(void)
RT_ASSERT(rt_interrupt_get_nest() > 0);
RT_OBJECT_HOOK_CALL(rt_tick_hook, ());
/* tracing cpu usage */
_update_process_times();
/* increase the global tick */
#ifdef RT_USING_SMP
/* get percpu and increase the tick */

View File

@ -346,9 +346,11 @@ void rt_thread_idle_init(void)
32);
#ifdef RT_USING_SMP
rt_thread_control(&idle_thread[i], RT_THREAD_CTRL_BIND_CPU, (void*)i);
rt_cpu_index(i)->idle_thread = &idle_thread[i];
#endif /* RT_USING_SMP */
/* update */
rt_cpu_index(i)->idle_thread = &idle_thread[i];
/* startup */
rt_thread_startup(&idle_thread[i]);
}