ソースを参照

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

xqyjlj 1 年間 前
コミット
d0dec5cbf2
1 ファイル変更26 行追加7 行削除
  1. 26 7
      src/thread.c

+ 26 - 7
src/thread.c

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