Browse Source

[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>
Shell 11 tháng trước cách đây
mục cha
commit
6ca327d8ce
6 tập tin đã thay đổi với 76 bổ sung52 xóa
  1. 3 3
      components/lwp/Kconfig
  2. 0 34
      components/lwp/lwp.c
  3. 28 14
      include/rtdef.h
  4. 8 0
      src/Kconfig
  5. 34 0
      src/clock.c
  6. 3 1
      src/idle.c

+ 3 - 3
components/lwp/Kconfig

@@ -12,9 +12,9 @@ if RT_USING_LWP
 
     if LWP_DEBUG
         config LWP_DEBUG_INIT
-        select RT_USING_HOOKLIST
-        bool "Enable debug mode of init process"
-        default n
+            select RT_USING_HOOKLIST
+            bool "Enable debug mode of init process"
+            default n
     endif
 
     config RT_LWP_MAX_NR

+ 0 - 34
components/lwp/lwp.c

@@ -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
-    }
-}

+ 28 - 14
include/rtdef.h

@@ -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 */
 
 /**@}*/

+ 8 - 0
src/Kconfig

@@ -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"

+ 34 - 0
src/clock.c

@@ -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 */

+ 3 - 1
src/idle.c

@@ -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);
+#endif /* RT_USING_SMP */
 
+        /* update */
         rt_cpu_index(i)->idle_thread = &idle_thread[i];
-#endif /* RT_USING_SMP */
+
         /* startup */
         rt_thread_startup(&idle_thread[i]);
     }