🐞 fix(thread): fix thread_exit/detach/delete (#8365)

This commit is contained in:
xqyjlj 2023-12-24 20:04:41 +08:00 committed by GitHub
parent fe35011fc5
commit d0dec5cbf2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 26 additions and 7 deletions

View File

@ -33,6 +33,7 @@
* 2022-01-24 THEWON let rt_thread_sleep return thread->error when using signal * 2022-01-24 THEWON let rt_thread_sleep return thread->error when using signal
* 2022-10-15 Bernard add nested mutex feature * 2022-10-15 Bernard add nested mutex feature
* 2023-09-15 xqyjlj perf rt_hw_interrupt_disable/enable * 2023-09-15 xqyjlj perf rt_hw_interrupt_disable/enable
* 2023-12-10 xqyjlj fix thread_exit/detach/delete
*/ */
#include <rthw.h> #include <rthw.h>
@ -99,17 +100,29 @@ static void _thread_exit(void)
rt_base_t level; rt_base_t level;
/* get current thread */ /* get current thread */
LOG_D("line:%d thread:%s exit\n",__LINE__,rt_thread_self()->parent.name);
thread = rt_thread_self(); thread = rt_thread_self();
rt_get_thread_struct(thread);
rt_thread_defunct_enqueue(thread); rt_enter_critical();
/* remove from schedule */
rt_schedule_remove_thread(thread);
level = rt_spin_lock_irqsave(&(thread->spinlock)); level = rt_spin_lock_irqsave(&(thread->spinlock));
/* remove it from timer list */
rt_timer_detach(&thread->thread_timer); rt_timer_detach(&thread->thread_timer);
/* insert to defunct thread list */
rt_spin_unlock_irqrestore(&(thread->spinlock), level); /* change stat */
LOG_D("line:%d thread:%s exit\n",__LINE__,rt_thread_self()->parent.name);
rt_put_thread_struct(thread);
thread->stat = RT_THREAD_CLOSE; thread->stat = RT_THREAD_CLOSE;
rt_spin_unlock_irqrestore(&(thread->spinlock), level);
/* insert to defunct thread list */
rt_thread_defunct_enqueue(thread);
LOG_D("line:%d thread:%s exit\n", __LINE__, rt_thread_self()->parent.name);
rt_exit_critical();
/* switch to next task */ /* switch to next task */
rt_schedule(); rt_schedule();
} }
@ -444,6 +457,8 @@ rt_err_t rt_thread_detach(rt_thread_t thread)
if ((thread->stat & RT_THREAD_STAT_MASK) == RT_THREAD_CLOSE) if ((thread->stat & RT_THREAD_STAT_MASK) == RT_THREAD_CLOSE)
return RT_EOK; return RT_EOK;
rt_enter_critical();
if ((thread->stat & RT_THREAD_STAT_MASK) != RT_THREAD_INIT) if ((thread->stat & RT_THREAD_STAT_MASK) != RT_THREAD_INIT)
{ {
/* remove from schedule */ /* remove from schedule */
@ -474,6 +489,7 @@ rt_err_t rt_thread_detach(rt_thread_t thread)
/* insert to defunct thread list */ /* insert to defunct thread list */
rt_thread_defunct_enqueue(thread); rt_thread_defunct_enqueue(thread);
rt_exit_critical();
return RT_EOK; return RT_EOK;
} }
RTM_EXPORT(rt_thread_detach); RTM_EXPORT(rt_thread_detach);
@ -556,6 +572,8 @@ rt_err_t rt_thread_delete(rt_thread_t thread)
if ((thread->stat & RT_THREAD_STAT_MASK) == RT_THREAD_CLOSE) if ((thread->stat & RT_THREAD_STAT_MASK) == RT_THREAD_CLOSE)
return RT_EOK; return RT_EOK;
rt_enter_critical();
if ((thread->stat & RT_THREAD_STAT_MASK) != RT_THREAD_INIT) if ((thread->stat & RT_THREAD_STAT_MASK) != RT_THREAD_INIT)
{ {
/* remove from schedule */ /* remove from schedule */
@ -583,6 +601,7 @@ rt_err_t rt_thread_delete(rt_thread_t thread)
/* insert to defunct thread list */ /* insert to defunct thread list */
rt_thread_defunct_enqueue(thread); rt_thread_defunct_enqueue(thread);
rt_exit_critical();
return RT_EOK; return RT_EOK;
} }
RTM_EXPORT(rt_thread_delete); RTM_EXPORT(rt_thread_delete);