summaryrefslogtreecommitdiff
path: root/src/cpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu.c')
-rw-r--r--src/cpu.c121
1 files changed, 56 insertions, 65 deletions
diff --git a/src/cpu.c b/src/cpu.c
index 0ecf67d1e5..8161b1aeb2 100644
--- a/src/cpu.c
+++ b/src/cpu.c
@@ -6,6 +6,7 @@
* Change Logs:
* Date Author Notes
* 2018-10-30 Bernard The first version
+ * 2023-09-15 xqyjlj perf rt_hw_interrupt_disable/enable
*/
#include <rthw.h>
#include <rtthread.h>
@@ -17,57 +18,19 @@
#ifdef RT_USING_SMP
static struct rt_cpu _cpus[RT_CPUS_NR];
rt_hw_spinlock_t _cpus_lock;
+#if defined(RT_DEBUGING_SPINLOCK)
+void *_cpus_lock_owner = 0;
+void *_cpus_lock_pc = 0;
-/*
- * @brief disable scheduler
- */
-static void _cpu_preempt_disable(void)
-{
- rt_base_t level;
- struct rt_thread *current_thread;
-
- /* disable interrupt */
- level = rt_hw_local_irq_disable();
+#define __OWNER_MAGIC ((void *)0xdeadbeaf)
- current_thread = rt_thread_self();
- if (!current_thread)
- {
- rt_hw_local_irq_enable(level);
- return;
- }
-
- /* lock scheduler for local cpu */
- current_thread->scheduler_lock_nest ++;
-
- /* enable interrupt */
- rt_hw_local_irq_enable(level);
-}
-
-/*
- * @brief enable scheduler
- */
-static void _cpu_preempt_enable(void)
-{
- rt_base_t level;
- struct rt_thread *current_thread;
-
- /* disable interrupt */
- level = rt_hw_local_irq_disable();
-
- current_thread = rt_thread_self();
- if (!current_thread)
- {
- rt_hw_local_irq_enable(level);
- return;
- }
-
- /* unlock scheduler for local cpu */
- current_thread->scheduler_lock_nest --;
+#if defined (__GNUC__)
+#define __GET_RETURN_ADDRESS __builtin_return_address(0)
+#else
+#define __GET_RETURN_ADDRESS RT_NULL
+#endif
- rt_schedule();
- /* enable interrupt */
- rt_hw_local_irq_enable(level);
-}
+#endif /* RT_DEBUGING_SPINLOCK */
/**
* @brief Initialize a static spinlock object.
@@ -90,8 +53,14 @@ RTM_EXPORT(rt_spin_lock_init)
*/
void rt_spin_lock(struct rt_spinlock *lock)
{
- _cpu_preempt_disable();
rt_hw_spin_lock(&lock->lock);
+#if defined(RT_DEBUGING_SPINLOCK)
+ if (rt_cpu_self() != RT_NULL)
+ {
+ lock->owner = rt_cpu_self()->current_thread;
+ }
+ lock->pc = __GET_RETURN_ADDRESS;
+#endif /* RT_DEBUGING_SPINLOCK */
}
RTM_EXPORT(rt_spin_lock)
@@ -103,7 +72,10 @@ RTM_EXPORT(rt_spin_lock)
void rt_spin_unlock(struct rt_spinlock *lock)
{
rt_hw_spin_unlock(&lock->lock);
- _cpu_preempt_enable();
+#if defined(RT_DEBUGING_SPINLOCK)
+ lock->owner = __OWNER_MAGIC;
+ lock->pc = RT_NULL;
+#endif /* RT_DEBUGING_SPINLOCK */
}
RTM_EXPORT(rt_spin_unlock)
@@ -121,11 +93,15 @@ rt_base_t rt_spin_lock_irqsave(struct rt_spinlock *lock)
{
unsigned long level;
- _cpu_preempt_disable();
-
level = rt_hw_local_irq_disable();
rt_hw_spin_lock(&lock->lock);
-
+#if defined(RT_DEBUGING_SPINLOCK)
+ if (rt_cpu_self() != RT_NULL)
+ {
+ lock->owner = rt_cpu_self()->current_thread;
+ lock->pc = __GET_RETURN_ADDRESS;
+ }
+#endif /* RT_DEBUGING_SPINLOCK */
return level;
}
RTM_EXPORT(rt_spin_lock_irqsave)
@@ -139,10 +115,12 @@ RTM_EXPORT(rt_spin_lock_irqsave)
*/
void rt_spin_unlock_irqrestore(struct rt_spinlock *lock, rt_base_t level)
{
+#if defined(RT_DEBUGING_SPINLOCK)
+ lock->owner = __OWNER_MAGIC;
+ lock->pc = RT_NULL;
+#endif /* RT_DEBUGING_SPINLOCK */
rt_hw_spin_unlock(&lock->lock);
rt_hw_local_irq_enable(level);
-
- _cpu_preempt_enable();
}
RTM_EXPORT(rt_spin_unlock_irqrestore)
@@ -183,13 +161,16 @@ rt_base_t rt_cpus_lock(void)
pcpu = rt_cpu_self();
if (pcpu->current_thread != RT_NULL)
{
- register rt_ubase_t lock_nest = pcpu->current_thread->cpus_lock_nest;
+ register rt_ubase_t lock_nest = rt_atomic_load(&(pcpu->current_thread->cpus_lock_nest));
- pcpu->current_thread->cpus_lock_nest++;
+ rt_atomic_add(&(pcpu->current_thread->cpus_lock_nest), 1);
if (lock_nest == 0)
{
- pcpu->current_thread->scheduler_lock_nest++;
rt_hw_spin_lock(&_cpus_lock);
+#if defined(RT_DEBUGING_SPINLOCK)
+ _cpus_lock_owner = pcpu->current_thread;
+ _cpus_lock_pc = __GET_RETURN_ADDRESS;
+#endif
}
}
@@ -208,12 +189,15 @@ void rt_cpus_unlock(rt_base_t level)
if (pcpu->current_thread != RT_NULL)
{
- RT_ASSERT(pcpu->current_thread->cpus_lock_nest > 0);
- pcpu->current_thread->cpus_lock_nest--;
+ RT_ASSERT(rt_atomic_load(&(pcpu->current_thread->cpus_lock_nest)) > 0);
+ rt_atomic_sub(&(pcpu->current_thread->cpus_lock_nest), 1);
if (pcpu->current_thread->cpus_lock_nest == 0)
{
- pcpu->current_thread->scheduler_lock_nest--;
+#if defined(RT_DEBUGING_SPINLOCK)
+ _cpus_lock_owner = __OWNER_MAGIC;
+ _cpus_lock_pc = RT_NULL;
+#endif
rt_hw_spin_unlock(&_cpus_lock);
}
}
@@ -235,11 +219,18 @@ void rt_cpus_lock_status_restore(struct rt_thread *thread)
#if defined(ARCH_MM_MMU) && defined(RT_USING_SMART)
lwp_aspace_switch(thread);
#endif
- pcpu->current_thread = thread;
- if (!thread->cpus_lock_nest)
+ if (pcpu->current_thread != RT_NULL )
{
- rt_hw_spin_unlock(&_cpus_lock);
+ rt_spin_unlock(&(pcpu->current_thread->spinlock));
+ if ((pcpu->current_thread->stat & RT_THREAD_STAT_MASK) == RT_THREAD_RUNNING)
+ {
+ rt_schedule_insert_thread(pcpu->current_thread);
+ }
+ rt_put_thread_struct(pcpu->current_thread);
+
}
+ pcpu->current_thread = thread;
+ rt_get_thread_struct(thread);
}
RTM_EXPORT(rt_cpus_lock_status_restore);
-#endif
+#endif /* RT_USING_SMP */