Browse Source

Merge pull request #4209 from jesven/cleanup

cleanup操作改由当前线程退出前执行
Bernard Xiong 4 years ago
parent
commit
a174881e0b
2 changed files with 50 additions and 66 deletions
  1. 17 62
      src/idle.c
  2. 33 4
      src/thread.c

+ 17 - 62
src/idle.c

@@ -150,82 +150,37 @@ void rt_thread_idle_excute(void)
 {
 {
     /* Loop until there is no dead thread. So one call to rt_thread_idle_excute
     /* Loop until there is no dead thread. So one call to rt_thread_idle_excute
      * will do all the cleanups. */
      * will do all the cleanups. */
-    while (_has_defunct_thread())
+    /* disable interrupt */
+
+    RT_DEBUG_NOT_IN_INTERRUPT;
+
+#ifdef RT_USING_HEAP
+    while (1)
     {
     {
         rt_base_t lock;
         rt_base_t lock;
         rt_thread_t thread;
         rt_thread_t thread;
-#ifdef RT_USING_MODULE
-        struct rt_dlmodule *module = RT_NULL;
-#endif
-        RT_DEBUG_NOT_IN_INTERRUPT;
 
 
-        /* disable interrupt */
         lock = rt_hw_interrupt_disable();
         lock = rt_hw_interrupt_disable();
 
 
-        /* re-check whether list is empty */
-        if (_has_defunct_thread())
-        {
-            /* get defunct thread */
-            thread = rt_list_entry(rt_thread_defunct.next,
-                                   struct rt_thread,
-                                   tlist);
-#ifdef RT_USING_MODULE
-            module = (struct rt_dlmodule*)thread->module_id;
-            if (module)
-            {
-                dlmodule_destroy(module);
-            }
-#endif
-            /* remove defunct thread */
-            rt_list_remove(&(thread->tlist));
-
-            /* lock scheduler to prevent scheduling in cleanup function. */
-            rt_enter_critical();
-
-            /* invoke thread cleanup */
-            if (thread->cleanup != RT_NULL)
-                thread->cleanup(thread);
-
-#ifdef RT_USING_SIGNALS
-            rt_thread_free_sig(thread);
-#endif
-
-            /* if it's a system object, not delete it */
-            if (rt_object_is_systemobject((rt_object_t)thread) == RT_TRUE)
-            {
-                /* detach this object */
-                rt_object_detach((rt_object_t)thread);
-                /* unlock scheduler */
-                rt_exit_critical();
-
-                /* enable interrupt */
-                rt_hw_interrupt_enable(lock);
-
-                return;
-            }
-
-            /* unlock scheduler */
-            rt_exit_critical();
-        }
-        else
+        /* check whether list is empty */
+        if (!_has_defunct_thread())
         {
         {
-            /* enable interrupt */
             rt_hw_interrupt_enable(lock);
             rt_hw_interrupt_enable(lock);
-
-            /* may the defunct thread list is removed by others, just return */
-            return;
+            break;
         }
         }
-
-        /* enable interrupt */
-        rt_hw_interrupt_enable(lock);
-
-#ifdef RT_USING_HEAP
+        /* get defunct thread */
+        thread = rt_list_entry(rt_thread_defunct.next,
+                struct rt_thread,
+                tlist);
+        /* remove defunct thread */
+        rt_list_remove(&(thread->tlist));
         /* release thread's stack */
         /* release thread's stack */
         RT_KERNEL_FREE(thread->stack_addr);
         RT_KERNEL_FREE(thread->stack_addr);
         /* delete thread object */
         /* delete thread object */
         rt_object_delete((rt_object_t)thread);
         rt_object_delete((rt_object_t)thread);
-#endif
+        rt_hw_interrupt_enable(lock);
     }
     }
+#endif
 }
 }
 
 
 extern void rt_system_power_manager(void);
 extern void rt_system_power_manager(void);

+ 33 - 4
src/thread.c

@@ -77,6 +77,31 @@ void rt_thread_inited_sethook(void (*hook)(rt_thread_t thread))
 
 
 #endif
 #endif
 
 
+/* must be invoke witch rt_hw_interrupt_disable */
+static void _thread_cleanup_execute(rt_thread_t thread)
+{
+    register rt_base_t level;
+#ifdef RT_USING_MODULE
+    struct rt_dlmodule *module = RT_NULL;
+#endif
+    level = rt_hw_interrupt_disable();
+#ifdef RT_USING_MODULE
+    module = (struct rt_dlmodule*)thread->module_id;
+    if (module)
+    {
+        dlmodule_destroy(module);
+    }
+#endif
+    /* invoke thread cleanup */
+    if (thread->cleanup != RT_NULL)
+        thread->cleanup(thread);
+
+#ifdef RT_USING_SIGNALS
+    rt_thread_free_sig(thread);
+#endif
+    rt_hw_interrupt_enable(level);
+}
+
 void rt_thread_exit(void)
 void rt_thread_exit(void)
 {
 {
     struct rt_thread *thread;
     struct rt_thread *thread;
@@ -88,6 +113,8 @@ void rt_thread_exit(void)
     /* disable interrupt */
     /* disable interrupt */
     level = rt_hw_interrupt_disable();
     level = rt_hw_interrupt_disable();
 
 
+    _thread_cleanup_execute(thread);
+
     /* remove from schedule */
     /* remove from schedule */
     rt_schedule_remove_thread(thread);
     rt_schedule_remove_thread(thread);
     /* change stat */
     /* change stat */
@@ -96,8 +123,7 @@ void rt_thread_exit(void)
     /* remove it from timer list */
     /* remove it from timer list */
     rt_timer_detach(&thread->thread_timer);
     rt_timer_detach(&thread->thread_timer);
 
 
-    if ((rt_object_is_systemobject((rt_object_t)thread) == RT_TRUE) &&
-        thread->cleanup == RT_NULL)
+    if (rt_object_is_systemobject((rt_object_t)thread) == RT_TRUE)
     {
     {
         rt_object_detach((rt_object_t)thread);
         rt_object_detach((rt_object_t)thread);
     }
     }
@@ -347,14 +373,15 @@ rt_err_t rt_thread_detach(rt_thread_t thread)
         rt_schedule_remove_thread(thread);
         rt_schedule_remove_thread(thread);
     }
     }
 
 
+    _thread_cleanup_execute(thread);
+
     /* release thread timer */
     /* release thread timer */
     rt_timer_detach(&(thread->thread_timer));
     rt_timer_detach(&(thread->thread_timer));
 
 
     /* change stat */
     /* change stat */
     thread->stat = RT_THREAD_CLOSE;
     thread->stat = RT_THREAD_CLOSE;
 
 
-    if ((rt_object_is_systemobject((rt_object_t)thread) == RT_TRUE) &&
-        thread->cleanup == RT_NULL)
+    if (rt_object_is_systemobject((rt_object_t)thread) == RT_TRUE)
     {
     {
         rt_object_detach((rt_object_t)thread);
         rt_object_detach((rt_object_t)thread);
     }
     }
@@ -449,6 +476,8 @@ rt_err_t rt_thread_delete(rt_thread_t thread)
         rt_schedule_remove_thread(thread);
         rt_schedule_remove_thread(thread);
     }
     }
 
 
+    _thread_cleanup_execute(thread);
+
     /* release thread timer */
     /* release thread timer */
     rt_timer_detach(&(thread->thread_timer));
     rt_timer_detach(&(thread->thread_timer));