summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/rtthread.h10
-rw-r--r--libcpu/aarch64/common/context_gcc.S15
-rw-r--r--src/clock.c2
-rw-r--r--src/cpu.c1
-rw-r--r--src/irq.c9
-rw-r--r--src/scheduler_mp.c14
-rw-r--r--src/timer.c2
7 files changed, 44 insertions, 9 deletions
diff --git a/include/rtthread.h b/include/rtthread.h
index 93fd138334..7ccf3b56c6 100644
--- a/include/rtthread.h
+++ b/include/rtthread.h
@@ -835,6 +835,16 @@ while (0)
#define RT_DEBUG_SCHEDULER_AVAILABLE(need_check)
#endif /* RT_DEBUGING_CONTEXT */
+rt_inline rt_bool_t rt_in_thread_context(void)
+{
+ return rt_thread_self() != RT_NULL && rt_interrupt_get_nest() == 0;
+}
+
+rt_inline rt_bool_t rt_scheduler_is_available(void)
+{
+ return !rt_hw_interrupt_is_disabled() && rt_critical_level() == 0 && rt_in_thread_context();
+}
+
/**@}*/
#ifdef __cplusplus
diff --git a/libcpu/aarch64/common/context_gcc.S b/libcpu/aarch64/common/context_gcc.S
index c671f9ba14..bbd7e72371 100644
--- a/libcpu/aarch64/common/context_gcc.S
+++ b/libcpu/aarch64/common/context_gcc.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006-2021, RT-Thread Development Team
+ * Copyright (c) 2006-2024, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -7,6 +7,7 @@
* Date Author Notes
* 2021-05-18 Jesven the first version
* 2023-06-24 WangXiaoyao Support backtrace for user thread
+ * 2024-01-06 Shell Fix barrier on irq_disable/enable
*/
#ifndef __ASSEMBLY__
@@ -36,8 +37,8 @@ int rt_hw_cpu_id(void)
.weak rt_hw_cpu_id
.type rt_hw_cpu_id, @function
rt_hw_cpu_id:
- mrs x0, tpidr_el1 /* MPIDR_EL1: Multi-Processor Affinity Register */
- ret
+ mrs x0, tpidr_el1
+ ret
/*
void rt_hw_set_process_id(size_t id)
@@ -314,7 +315,8 @@ rt_hw_interrupt_is_disabled:
rt_hw_interrupt_disable:
MRS X0, DAIF
MSR DAIFSet, #3
- DSB SY
+ DSB NSH
+ ISB
RET
/*
@@ -322,7 +324,8 @@ rt_hw_interrupt_disable:
*/
.globl rt_hw_interrupt_enable
rt_hw_interrupt_enable:
- DSB SY
+ ISB
+ DSB NSH
AND X0, X0, #0xc0
MRS X1, DAIF
BIC X1, X1, #0xc0
@@ -580,4 +583,4 @@ START_POINT(vector_serror)
STP X0, X1, [SP, #-0x10]!
BL rt_hw_trap_serror
b .
-START_POINT_END(vector_exception)
+START_POINT_END(vector_serror)
diff --git a/src/clock.c b/src/clock.c
index a5f5d5e9f1..88f443ee0e 100644
--- a/src/clock.c
+++ b/src/clock.c
@@ -89,6 +89,8 @@ void rt_tick_increase(void)
rt_base_t level;
rt_atomic_t oldval = 0;
+ RT_ASSERT(rt_interrupt_get_nest() > 0);
+
RT_OBJECT_HOOK_CALL(rt_tick_hook, ());
/* increase the global tick */
#ifdef RT_USING_SMP
diff --git a/src/cpu.c b/src/cpu.c
index 686b67a4ea..f8b8905056 100644
--- a/src/cpu.c
+++ b/src/cpu.c
@@ -136,6 +136,7 @@ RTM_EXPORT(rt_spin_unlock_irqrestore)
*/
struct rt_cpu *rt_cpu_self(void)
{
+ RT_ASSERT(!rt_scheduler_is_available());
return &_cpus[rt_hw_cpu_id()];
}
diff --git a/src/irq.c b/src/irq.c
index 03287200cf..fb5a50275a 100644
--- a/src/irq.c
+++ b/src/irq.c
@@ -13,6 +13,7 @@
* 2022-01-07 Gabriel Moving __on_rt_xxxxx_hook to irq.c
* 2022-07-04 Yunjie fix RT_DEBUG_LOG
* 2023-09-15 xqyjlj perf rt_hw_interrupt_disable/enable
+ * 2024-01-05 Shell Fixup of data racing in rt_interrupt_get_nest
*/
#include <rthw.h>
@@ -114,7 +115,13 @@ RTM_EXPORT(rt_interrupt_leave);
*/
rt_weak rt_uint8_t rt_interrupt_get_nest(void)
{
- return rt_atomic_load(&rt_interrupt_nest);
+ rt_uint8_t ret;
+ rt_base_t level;
+
+ level = rt_hw_local_irq_disable();
+ ret = rt_atomic_load(&rt_interrupt_nest);
+ rt_hw_local_irq_enable(level);
+ return ret;
}
RTM_EXPORT(rt_interrupt_get_nest);
diff --git a/src/scheduler_mp.c b/src/scheduler_mp.c
index 06193c388e..fdd148b1ca 100644
--- a/src/scheduler_mp.c
+++ b/src/scheduler_mp.c
@@ -31,6 +31,7 @@
* 2023-03-27 rose_man Split into scheduler upc and scheduler_mp.c
* 2023-09-15 xqyjlj perf rt_hw_interrupt_disable/enable
* 2023-12-10 xqyjlj use rt_hw_spinlock
+ * 2024-01-05 Shell Fixup of data racing in rt_critical_level
*/
#include <rtthread.h>
@@ -848,8 +849,17 @@ RTM_EXPORT(rt_exit_critical);
*/
rt_uint16_t rt_critical_level(void)
{
- struct rt_thread *current_thread = rt_cpu_self()->current_thread;
- return rt_atomic_load(&(current_thread->critical_lock_nest));
+ rt_base_t level;
+ rt_uint16_t critical_lvl;
+ struct rt_thread *current_thread;
+
+ level = rt_hw_local_irq_disable();
+
+ current_thread = rt_cpu_self()->current_thread;
+ critical_lvl = rt_atomic_load(&(current_thread->critical_lock_nest));
+
+ rt_hw_local_irq_enable(level);
+ return critical_lvl;
}
RTM_EXPORT(rt_critical_level);
diff --git a/src/timer.c b/src/timer.c
index 2f1ad9c718..3520b5cde5 100644
--- a/src/timer.c
+++ b/src/timer.c
@@ -658,6 +658,8 @@ void rt_timer_check(void)
rt_base_t level;
rt_list_t list;
+ RT_ASSERT(rt_interrupt_get_nest() > 0);
+
#ifdef RT_USING_SMP
if (rt_hw_cpu_id() != 0)
{