Browse Source

remove duplicate work between idle and thread_exit

thewon86 3 years ago
parent
commit
5ae6b54e21
2 changed files with 38 additions and 103 deletions
  1. 21 46
      src/idle.c
  2. 17 57
      src/thread.c

+ 21 - 46
src/idle.c

@@ -15,6 +15,7 @@
  * 2018-07-14     armink       add idle hook list
  * 2018-11-22     Jesven       add per cpu idle task
  *                             combine the code of primary and secondary cpu
+ * 2021-11-15     THEWON       Remove duplicate work between idle and _thread_exit
  */
 
 #include <rthw.h>
@@ -136,22 +137,6 @@ rt_err_t rt_thread_idle_delhook(void (*hook)(void))
 
 #endif /* RT_USING_IDLE_HOOK */
 
-#ifdef RT_USING_MODULE
-/* Return whether there is defunctional thread to be deleted. */
-rt_inline int _idle_has_defunct_thread(void)
-{
-    /* The rt_list_isempty has prototype of "int rt_list_isempty(const rt_list_t *l)".
-     * So the compiler has a good reason that the _rt_thread_defunct list does
-     * not change within rt_thread_defunct_exceute thus optimize the "while" loop
-     * into a "if".
-     *
-     * So add the volatile qualifier here. */
-    const volatile rt_list_t *l = (const volatile rt_list_t *)&_rt_thread_defunct;
-
-    return l->next != l;
-}
-#endif /* RT_USING_MODULE */
-
 /**
  * @brief Enqueue a thread to defunct queue.
  *
@@ -167,14 +152,16 @@ void rt_thread_defunct_enqueue(rt_thread_t thread)
 
 /**
  * @brief Dequeue a thread from defunct queue.
- *
- * @note It must be called between rt_hw_interrupt_disable and rt_hw_interrupt_enable.
  */
 rt_thread_t rt_thread_defunct_dequeue(void)
 {
+    register rt_base_t lock;
     rt_thread_t thread = RT_NULL;
     rt_list_t *l = &_rt_thread_defunct;
 
+#ifdef RT_USING_SMP
+    /* disable interrupt */
+    lock = rt_hw_interrupt_disable();
     if (l->next != l)
     {
         thread = rt_list_entry(l->next,
@@ -182,6 +169,18 @@ rt_thread_t rt_thread_defunct_dequeue(void)
                 tlist);
         rt_list_remove(&(thread->tlist));
     }
+    rt_hw_interrupt_enable(lock);
+#else
+    if (l->next != l)
+    {
+        thread = rt_list_entry(l->next,
+                struct rt_thread,
+                tlist);
+        lock = rt_hw_interrupt_disable();
+        rt_list_remove(&(thread->tlist));
+        rt_hw_interrupt_enable(lock);
+    }
+#endif
     return thread;
 }
 
@@ -194,51 +193,30 @@ static void rt_defunct_execute(void)
      * will do all the cleanups. */
     while (1)
     {
-        rt_base_t lock;
         rt_thread_t thread;
         void (*cleanup)(struct rt_thread *tid);
 
 #ifdef RT_USING_MODULE
         struct rt_dlmodule *module = RT_NULL;
 #endif
-        RT_DEBUG_NOT_IN_INTERRUPT;
-
-        /* disable interrupt */
-        lock = rt_hw_interrupt_disable();
-
-#ifdef RT_USING_MODULE
-        /* check whether list is empty */
-        if (!_idle_has_defunct_thread())
+        /* get defunct thread */
+        thread = rt_thread_defunct_dequeue();
+        if (thread == RT_NULL)
         {
-            rt_hw_interrupt_enable(lock);
             break;
         }
-        /* 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);
         }
-        /* remove defunct thread */
-        rt_list_remove(&(thread->tlist));
-#else
-        thread = rt_thread_defunct_dequeue();
-        if (!thread)
-        {
-            rt_hw_interrupt_enable(lock);
-            break;
-        }
 #endif
         /* invoke thread cleanup */
         cleanup = thread->cleanup;
         if (cleanup != RT_NULL)
         {
-            rt_hw_interrupt_enable(lock);
             cleanup(thread);
-            lock = rt_hw_interrupt_disable();
         }
 
 #ifdef RT_USING_SIGNALS
@@ -250,12 +228,9 @@ static void rt_defunct_execute(void)
         {
             /* detach this object */
             rt_object_detach((rt_object_t)thread);
-            /* enable interrupt */
-            rt_hw_interrupt_enable(lock);
         }
         else
         {
-            rt_hw_interrupt_enable(lock);
 #ifdef RT_USING_HEAP
             /* release thread's stack */
             RT_KERNEL_FREE(thread->stack_addr);

+ 17 - 57
src/thread.c

@@ -27,6 +27,7 @@
  * 2018-11-22     Jesven       yield is same to rt_schedule
  *                             add support for tasks bound to cpu
  * 2021-02-24     Meco Man     rearrange rt_thread_control() - schedule the thread when close it
+ * 2021-11-15     THEWON       Remove duplicate work between idle and _thread_exit
  */
 
 #include <rthw.h>
@@ -73,30 +74,6 @@ void rt_thread_inited_sethook(void (*hook)(rt_thread_t thread))
 
 #endif /* RT_USING_HOOK */
 
-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 /* RT_USING_MODULE */
-    level = rt_hw_interrupt_disable();
-#ifdef RT_USING_MODULE
-    module = (struct rt_dlmodule*)thread->module_id;
-    if (module)
-    {
-        dlmodule_destroy(module);
-    }
-#endif /* RT_USING_MODULE */
-    /* invoke thread cleanup */
-    if (thread->cleanup != RT_NULL)
-        thread->cleanup(thread);
-
-#ifdef RT_USING_SIGNALS
-    rt_thread_free_sig(thread);
-#endif /* RT_USING_SIGNALS */
-    rt_hw_interrupt_enable(level);
-}
-
 static void _thread_exit(void)
 {
     struct rt_thread *thread;
@@ -108,31 +85,23 @@ static void _thread_exit(void)
     /* disable interrupt */
     level = rt_hw_interrupt_disable();
 
-    _thread_cleanup_execute(thread);
-
     /* remove from schedule */
     rt_schedule_remove_thread(thread);
-    /* change stat */
-    thread->stat = RT_THREAD_CLOSE;
 
     /* remove it from timer list */
     rt_timer_detach(&thread->thread_timer);
 
-    if (rt_object_is_systemobject((rt_object_t)thread) == RT_TRUE)
-    {
-        rt_object_detach((rt_object_t)thread);
-    }
-    else
-    {
-        /* insert to defunct thread list */
-        rt_thread_defunct_enqueue(thread);
-    }
+    /* change stat */
+    thread->stat = RT_THREAD_CLOSE;
 
-    /* switch to next task */
-    rt_schedule();
+    /* insert to defunct thread list */
+    rt_thread_defunct_enqueue(thread);
 
     /* enable interrupt */
     rt_hw_interrupt_enable(level);
+
+    /* switch to next task */
+    rt_schedule();
 }
 
 static rt_err_t _thread_init(struct rt_thread *thread,
@@ -382,7 +351,8 @@ rt_err_t rt_thread_detach(rt_thread_t thread)
         rt_schedule_remove_thread(thread);
     }
 
-    _thread_cleanup_execute(thread);
+    /* disable interrupt */
+    lock = rt_hw_interrupt_disable();
 
     /* release thread timer */
     rt_timer_detach(&(thread->thread_timer));
@@ -390,19 +360,11 @@ rt_err_t rt_thread_detach(rt_thread_t thread)
     /* change stat */
     thread->stat = RT_THREAD_CLOSE;
 
-    if (rt_object_is_systemobject((rt_object_t)thread) == RT_TRUE)
-    {
-        rt_object_detach((rt_object_t)thread);
-    }
-    else
-    {
-        /* disable interrupt */
-        lock = rt_hw_interrupt_disable();
-        /* insert to defunct thread list */
-        rt_thread_defunct_enqueue(thread);
-        /* enable interrupt */
-        rt_hw_interrupt_enable(lock);
-    }
+    /* insert to defunct thread list */
+    rt_thread_defunct_enqueue(thread);
+
+    /* enable interrupt */
+    rt_hw_interrupt_enable(lock);
 
     return RT_EOK;
 }
@@ -492,14 +454,12 @@ rt_err_t rt_thread_delete(rt_thread_t thread)
         rt_schedule_remove_thread(thread);
     }
 
-    _thread_cleanup_execute(thread);
+    /* disable interrupt */
+    lock = rt_hw_interrupt_disable();
 
     /* release thread timer */
     rt_timer_detach(&(thread->thread_timer));
 
-    /* disable interrupt */
-    lock = rt_hw_interrupt_disable();
-
     /* change stat */
     thread->stat = RT_THREAD_CLOSE;