diff options
| author | Bernard Xiong <[email protected]> | 2020-07-29 11:08:18 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2020-07-29 11:08:18 +0800 |
| commit | 4f674ef1499139acb06db82d36817d64d92653cb (patch) | |
| tree | d4ee5dd07bd9686c58bcd07afc54d175656b31bb | |
| parent | 18d1683092fef9d350d01b65c688ca4f65c32af0 (diff) | |
| parent | 0e619491163d2e2b4c1cc262f0faee3b1ced55b7 (diff) | |
Merge pull request #3786 from jesven/avoid_critical_deadlock
avoid deadlock (rt_hw_interrupt_disable and rt_enter_critical when en…
| -rw-r--r-- | src/scheduler.c | 25 |
1 files changed, 13 insertions, 12 deletions
diff --git a/src/scheduler.c b/src/scheduler.c index 6baaa9627a..0c1bf1e506 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -33,10 +33,6 @@ #include <rtthread.h> #include <rthw.h> -#ifdef RT_USING_SMP -rt_hw_spinlock_t _rt_critical_lock; -#endif /*RT_USING_SMP*/ - rt_list_t rt_thread_priority_table[RT_THREAD_PRIORITY_MAX]; rt_uint32_t rt_thread_ready_priority_group; #if RT_THREAD_PRIORITY_MAX > 32 @@ -851,7 +847,7 @@ void rt_enter_critical(void) if (!current_thread) { rt_hw_local_irq_enable(level); - return ; + return; } /* @@ -859,12 +855,15 @@ void rt_enter_critical(void) * enough and does not check here */ - /* lock scheduler for all cpus */ - if (current_thread->critical_lock_nest == 0) { - rt_hw_spin_lock(&_rt_critical_lock); + register rt_uint16_t lock_nest = current_thread->cpus_lock_nest; + current_thread->cpus_lock_nest++; + if (lock_nest == 0) + { + current_thread->scheduler_lock_nest ++; + rt_hw_spin_lock(&_cpus_lock); + } } - /* critical for local cpu */ current_thread->critical_lock_nest ++; @@ -910,16 +909,18 @@ void rt_exit_critical(void) if (!current_thread) { rt_hw_local_irq_enable(level); - return ; + return; } current_thread->scheduler_lock_nest --; current_thread->critical_lock_nest --; - if (current_thread->critical_lock_nest == 0) + current_thread->cpus_lock_nest--; + if (current_thread->cpus_lock_nest == 0) { - rt_hw_spin_unlock(&_rt_critical_lock); + current_thread->scheduler_lock_nest --; + rt_hw_spin_unlock(&_cpus_lock); } if (current_thread->scheduler_lock_nest <= 0) |
