From fc86f6b9a01d28640e4184e5f0b275eeda11b301 Mon Sep 17 00:00:00 2001 From: Shell Date: Tue, 30 Apr 2024 23:57:03 +0800 Subject: [PATCH 1/4] [src] add rt_hw_cpu_id() wrapper API rt_hw_cpu_id() is an unsafe API which should not be used by most codes directly. It's error-prone because it must be used in proper context, otherwise it can lead to errors and unpredictable behavior. This patch adds a wrapper API for rt_hw_cpu_id() to address this risk. It includes the context-checking functionality and provides a safer alternative for obtaining CPU IDs, ensuring that it is used correctly within the appropriate context. Signed-off-by: Shell --- include/rtthread.h | 23 +++++++++++++++++++++-- src/clock.c | 2 +- src/idle.c | 4 ++-- src/signal.c | 4 ++-- src/timer.c | 2 +- 5 files changed, 27 insertions(+), 8 deletions(-) diff --git a/include/rtthread.h b/include/rtthread.h index 5e70c5dd63f..20bb282f9f3 100644 --- a/include/rtthread.h +++ b/include/rtthread.h @@ -780,7 +780,6 @@ while (0) * 1) the scheduler has been started. * 2) not in interrupt context. * 3) scheduler is not locked. - * 4) interrupt is not disabled. */ #define RT_DEBUG_SCHEDULER_AVAILABLE(need_check) \ do \ @@ -810,7 +809,27 @@ rt_inline rt_bool_t rt_in_thread_context(void) rt_inline rt_bool_t rt_scheduler_is_available(void) { - return !rt_hw_interrupt_is_disabled() && rt_critical_level() == 0 && rt_in_thread_context(); + return rt_critical_level() == 0 && rt_in_thread_context(); +} + +rt_inline rt_bool_t rt_scheduler_is_binding(rt_thread_t thread) +{ + if (thread == RT_NULL) + { + thread = rt_thread_self(); + } + return !thread || RT_SCHED_CTX(thread).bind_cpu != RT_CPUS_NR; +} + +/* A safe API with debugging feature to be called in most codes */ +rt_inline rt_base_t rt_cpu_get_id(void) +{ + + RT_ASSERT(rt_scheduler_is_binding(RT_NULL) || + rt_hw_interrupt_is_disabled() || + !rt_scheduler_is_available()); + + return rt_hw_cpu_id(); } /**@}*/ diff --git a/src/clock.c b/src/clock.c index 42e361226f6..c2fe321c33f 100644 --- a/src/clock.c +++ b/src/clock.c @@ -101,7 +101,7 @@ void rt_tick_increase(void) /* check timer */ #ifdef RT_USING_SMP - if (rt_hw_cpu_id() != 0) + if (rt_cpu_get_id() != 0) { return; } diff --git a/src/idle.c b/src/idle.c index 054e525ef3c..bd2bb752778 100644 --- a/src/idle.c +++ b/src/idle.c @@ -261,7 +261,7 @@ static void idle_thread_entry(void *parameter) { RT_UNUSED(parameter); #ifdef RT_USING_SMP - if (rt_hw_cpu_id() != 0) + if (rt_cpu_get_id() != 0) { while (1) { @@ -381,7 +381,7 @@ void rt_thread_idle_init(void) rt_thread_t rt_thread_idle_gethandler(void) { #ifdef RT_USING_SMP - int id = rt_hw_cpu_id(); + int id = rt_cpu_get_id(); #else int id = 0; #endif /* RT_USING_SMP */ diff --git a/src/signal.c b/src/signal.c index 28d0fd1c9f1..552d2a89cd2 100644 --- a/src/signal.c +++ b/src/signal.c @@ -142,7 +142,7 @@ static void _signal_deliver(rt_thread_t tid) int cpu_id; cpu_id = RT_SCHED_CTX(tid).oncpu; - if ((cpu_id != RT_CPU_DETACHED) && (cpu_id != rt_hw_cpu_id())) + if ((cpu_id != RT_CPU_DETACHED) && (cpu_id != rt_cpu_get_id())) { rt_uint32_t cpu_mask; @@ -181,7 +181,7 @@ void *rt_signal_check(void* context) level = rt_spin_lock_irqsave(&_thread_signal_lock); - cpu_id = rt_hw_cpu_id(); + cpu_id = rt_cpu_get_id(); pcpu = rt_cpu_index(cpu_id); current_thread = pcpu->current_thread; diff --git a/src/timer.c b/src/timer.c index 4d7b352d605..143bbebb12b 100644 --- a/src/timer.c +++ b/src/timer.c @@ -684,7 +684,7 @@ void rt_timer_check(void) #ifdef RT_USING_SMP /* Running on core 0 only */ - if (rt_hw_cpu_id() != 0) + if (rt_cpu_get_id() != 0) { rt_spin_unlock_irqrestore(&_htimer_lock, level); return; From e8a71079b953e63c9e31e7a551f25b72342512c6 Mon Sep 17 00:00:00 2001 From: Shell Date: Wed, 1 May 2024 00:11:32 +0800 Subject: [PATCH 2/4] fixup UMP --- include/rtthread.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/rtthread.h b/include/rtthread.h index 20bb282f9f3..632758d5367 100644 --- a/include/rtthread.h +++ b/include/rtthread.h @@ -812,6 +812,7 @@ rt_inline rt_bool_t rt_scheduler_is_available(void) return rt_critical_level() == 0 && rt_in_thread_context(); } +#ifdef RT_USING_SMP rt_inline rt_bool_t rt_scheduler_is_binding(rt_thread_t thread) { if (thread == RT_NULL) @@ -821,6 +822,10 @@ rt_inline rt_bool_t rt_scheduler_is_binding(rt_thread_t thread) return !thread || RT_SCHED_CTX(thread).bind_cpu != RT_CPUS_NR; } +#else +#define rt_scheduler_is_binding(thread) (RT_TRUE) +#endif + /* A safe API with debugging feature to be called in most codes */ rt_inline rt_base_t rt_cpu_get_id(void) { From eea39927077530b7d776bca6aa1f7890d34eb08e Mon Sep 17 00:00:00 2001 From: Shell Date: Mon, 6 May 2024 10:47:25 +0800 Subject: [PATCH 3/4] update API & comment --- include/rtthread.h | 27 +++++++++++++-------------- src/cpu_mp.c | 17 +++++++++++++++++ src/idle.c | 4 ---- 3 files changed, 30 insertions(+), 18 deletions(-) diff --git a/include/rtthread.h b/include/rtthread.h index 632758d5367..52f99f2a590 100644 --- a/include/rtthread.h +++ b/include/rtthread.h @@ -675,11 +675,19 @@ void rt_interrupt_leave(void); rt_base_t rt_cpus_lock(void); void rt_cpus_unlock(rt_base_t level); +void rt_cpus_lock_status_restore(struct rt_thread *thread); struct rt_cpu *rt_cpu_self(void); struct rt_cpu *rt_cpu_index(int index); -void rt_cpus_lock_status_restore(struct rt_thread *thread); +#ifdef RT_USING_DEBUG + rt_base_t rt_cpu_get_id(void); +#else /* !RT_USING_DEBUG */ + #define rt_cpu_get_id rt_hw_cpu_id +#endif /* RT_USING_DEBUG */ + +#else /* !RT_USING_SMP */ +#define rt_cpu_get_id() (0) #endif /* RT_USING_SMP */ @@ -807,13 +815,15 @@ rt_inline rt_bool_t rt_in_thread_context(void) return rt_thread_self() != RT_NULL && rt_interrupt_get_nest() == 0; } +/* is scheduler available */ rt_inline rt_bool_t rt_scheduler_is_available(void) { return rt_critical_level() == 0 && rt_in_thread_context(); } #ifdef RT_USING_SMP -rt_inline rt_bool_t rt_scheduler_is_binding(rt_thread_t thread) +/* is thread bond on core */ +rt_inline rt_bool_t rt_sched_thread_is_binding(rt_thread_t thread) { if (thread == RT_NULL) { @@ -823,20 +833,9 @@ rt_inline rt_bool_t rt_scheduler_is_binding(rt_thread_t thread) } #else -#define rt_scheduler_is_binding(thread) (RT_TRUE) +#define rt_sched_thread_is_binding(thread) (RT_TRUE) #endif -/* A safe API with debugging feature to be called in most codes */ -rt_inline rt_base_t rt_cpu_get_id(void) -{ - - RT_ASSERT(rt_scheduler_is_binding(RT_NULL) || - rt_hw_interrupt_is_disabled() || - !rt_scheduler_is_available()); - - return rt_hw_cpu_id(); -} - /**@}*/ #ifdef __cplusplus diff --git a/src/cpu_mp.c b/src/cpu_mp.c index c27374707c3..8da4c3e1802 100644 --- a/src/cpu_mp.c +++ b/src/cpu_mp.c @@ -216,3 +216,20 @@ void rt_cpus_lock_status_restore(struct rt_thread *thread) rt_sched_post_ctx_switch(thread); } RTM_EXPORT(rt_cpus_lock_status_restore); + +/* A safe API with debugging feature to be called in most codes */ + +/** + * @brief Get logical CPU ID + * + * @return logical CPU ID + */ +rt_base_t rt_cpu_get_id(void) +{ + + RT_ASSERT(rt_sched_thread_is_binding(RT_NULL) || + rt_hw_interrupt_is_disabled() || + !rt_scheduler_is_available()); + + return rt_hw_cpu_id(); +} diff --git a/src/idle.c b/src/idle.c index bd2bb752778..a428a649c10 100644 --- a/src/idle.c +++ b/src/idle.c @@ -380,11 +380,7 @@ void rt_thread_idle_init(void) */ rt_thread_t rt_thread_idle_gethandler(void) { -#ifdef RT_USING_SMP int id = rt_cpu_get_id(); -#else - int id = 0; -#endif /* RT_USING_SMP */ return (rt_thread_t)(&idle_thread[id]); } From 56ff980c70396962c02f83d4d00d900ba7c58202 Mon Sep 17 00:00:00 2001 From: Shell Date: Mon, 6 May 2024 11:02:30 +0800 Subject: [PATCH 4/4] ci: cpp_check --- tools/ci/cpp_check.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/ci/cpp_check.py b/tools/ci/cpp_check.py index e7b2847c4a5..5e7e1005257 100644 --- a/tools/ci/cpp_check.py +++ b/tools/ci/cpp_check.py @@ -27,6 +27,7 @@ def check(self): [ 'cppcheck', '-DRT_ASSERT(x)=', + '-DRTM_EXPORT(x)=', '-Drt_list_for_each_entry(a,b,c)=a=(void*)b;', '-I include', '-I thread/components/finsh',