Browse Source

分离defunct

heyuanjie87 10 months ago
parent
commit
2351981e83
4 changed files with 177 additions and 177 deletions
  1. 1 0
      include/rtthread.h
  2. 3 0
      src/components.c
  3. 171 0
      src/defunct.c
  4. 2 177
      src/idle.c

+ 1 - 0
include/rtthread.h

@@ -641,6 +641,7 @@ rt_ssize_t rt_mq_recv_prio(rt_mq_t mq,
 /**@}*/
 /**@}*/
 
 
 /* defunct */
 /* defunct */
+void rt_thread_defunct_init(void);
 void rt_thread_defunct_enqueue(rt_thread_t thread);
 void rt_thread_defunct_enqueue(rt_thread_t thread);
 rt_thread_t rt_thread_defunct_dequeue(void);
 rt_thread_t rt_thread_defunct_dequeue(void);
 
 

+ 3 - 0
src/components.c

@@ -270,6 +270,9 @@ int rtthread_startup(void)
     /* idle thread initialization */
     /* idle thread initialization */
     rt_thread_idle_init();
     rt_thread_idle_init();
 
 
+    /* defunct thread initialization */
+    rt_thread_defunct_init();
+
 #ifdef RT_USING_SMP
 #ifdef RT_USING_SMP
     rt_hw_spin_lock(&_cpus_lock);
     rt_hw_spin_lock(&_cpus_lock);
 #endif /* RT_USING_SMP */
 #endif /* RT_USING_SMP */

+ 171 - 0
src/defunct.c

@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2024-08-30     heyuanjie87  the first version
+ * 
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+
+#ifndef SYSTEM_THREAD_STACK_SIZE
+#define SYSTEM_THREAD_STACK_SIZE IDLE_THREAD_STACK_SIZE
+#endif
+static rt_list_t _rt_thread_defunct = RT_LIST_OBJECT_INIT(_rt_thread_defunct);
+static struct rt_spinlock _defunct_spinlock;
+static struct rt_thread rt_system_thread;
+rt_align(RT_ALIGN_SIZE) static rt_uint8_t rt_system_stack[SYSTEM_THREAD_STACK_SIZE];
+static struct rt_semaphore system_sem;
+
+/**
+ * @brief Enqueue a thread to defunct queue.
+ *
+ * @param thread the thread to be enqueued.
+ *
+ * @note It must be called between rt_hw_interrupt_disable and rt_hw_interrupt_enable
+ */
+void rt_thread_defunct_enqueue(rt_thread_t thread)
+{
+    rt_base_t level;
+    level = rt_spin_lock_irqsave(&_defunct_spinlock);
+    rt_list_insert_after(&_rt_thread_defunct, &RT_THREAD_LIST_NODE(thread));
+    rt_spin_unlock_irqrestore(&_defunct_spinlock, level);
+
+    rt_sem_release(&system_sem);
+}
+
+/**
+ * @brief Dequeue a thread from defunct queue.
+ */
+rt_thread_t rt_thread_defunct_dequeue(void)
+{
+    rt_base_t   level;
+    rt_thread_t thread = RT_NULL;
+    rt_list_t  *l      = &_rt_thread_defunct;
+
+    level = rt_spin_lock_irqsave(&_defunct_spinlock);
+    if (l->next != l)
+    {
+        thread = RT_THREAD_LIST_NODE_ENTRY(l->next);
+        rt_list_remove(&RT_THREAD_LIST_NODE(thread));
+    }
+    rt_spin_unlock_irqrestore(&_defunct_spinlock, level);
+
+    return thread;
+}
+
+/**
+ * @brief This function will perform system background job when system idle.
+ */
+static void rt_defunct_execute(void)
+{
+    /* Loop until there is no dead thread. So one call to rt_defunct_execute
+     * will do all the cleanups. */
+    while (1)
+    {
+        rt_thread_t thread;
+        rt_bool_t   object_is_systemobject;
+        void (*cleanup)(struct rt_thread *tid);
+
+#ifdef RT_USING_MODULE
+        struct rt_dlmodule *module = RT_NULL;
+#endif
+        /* get defunct thread */
+        thread = rt_thread_defunct_dequeue();
+        if (thread == RT_NULL)
+        {
+            break;
+        }
+
+#ifdef RT_USING_MODULE
+        module = (struct rt_dlmodule *)thread->parent.module_id;
+        if (module)
+        {
+            dlmodule_destroy(module);
+        }
+#endif
+
+#ifdef RT_USING_SIGNALS
+        rt_thread_free_sig(thread);
+#endif
+
+        /* store the point of "thread->cleanup" avoid to lose */
+        cleanup = thread->cleanup;
+
+        /* if it's a system object, detach it */
+        object_is_systemobject = rt_object_is_systemobject((rt_object_t)thread);
+        if (object_is_systemobject == RT_TRUE)
+        {
+            /* detach this object */
+            rt_object_detach((rt_object_t)thread);
+        }
+
+        /* invoke thread cleanup */
+        if (cleanup != RT_NULL)
+        {
+            cleanup(thread);
+        }
+
+#ifdef RT_USING_HEAP
+#ifdef RT_USING_MEM_PROTECTION
+        if (thread->mem_regions != RT_NULL)
+        {
+            RT_KERNEL_FREE(thread->mem_regions);
+        }
+#endif
+        /* if need free, delete it */
+        if (object_is_systemobject == RT_FALSE)
+        {
+            /* release thread's stack */
+#ifdef RT_USING_HW_STACK_GUARD
+            RT_KERNEL_FREE(thread->stack_buf);
+#else
+            RT_KERNEL_FREE(thread->stack_addr);
+#endif
+            /* delete thread object */
+            rt_object_delete((rt_object_t)thread);
+        }
+#endif
+    }
+}
+
+static void rt_thread_system_entry(void *parameter)
+{
+    RT_UNUSED(parameter);
+
+    while (1)
+    {
+        int ret = rt_sem_take(&system_sem, RT_WAITING_FOREVER);
+        if (ret != RT_EOK)
+        {
+            rt_kprintf("failed to sem_take() error %d\n", ret);
+            RT_ASSERT(0);
+        }
+        rt_defunct_execute();
+    }
+}
+
+void rt_thread_defunct_init(void)
+{
+    RT_ASSERT(RT_THREAD_PRIORITY_MAX > 2);
+
+    rt_spin_lock_init(&_defunct_spinlock);
+
+    rt_sem_init(&system_sem, "defunct", 0, RT_IPC_FLAG_FIFO);
+
+    /* create defunct thread */
+    rt_thread_init(&rt_system_thread,
+                   "tsystem",
+                   rt_thread_system_entry,
+                   RT_NULL,
+                   rt_system_stack,
+                   sizeof(rt_system_stack),
+                   RT_THREAD_PRIORITY_MAX - 2,
+                   32);
+    /* startup */
+    rt_thread_startup(&rt_system_thread);
+}

+ 2 - 177
src/idle.c

@@ -44,22 +44,10 @@
 
 
 #define _CPUS_NR                RT_CPUS_NR
 #define _CPUS_NR                RT_CPUS_NR
 
 
-static rt_list_t _rt_thread_defunct = RT_LIST_OBJECT_INIT(_rt_thread_defunct);
-static struct rt_spinlock _defunct_spinlock;
 static struct rt_thread idle_thread[_CPUS_NR];
 static struct rt_thread idle_thread[_CPUS_NR];
 rt_align(RT_ALIGN_SIZE)
 rt_align(RT_ALIGN_SIZE)
 static rt_uint8_t idle_thread_stack[_CPUS_NR][IDLE_THREAD_STACK_SIZE];
 static rt_uint8_t idle_thread_stack[_CPUS_NR][IDLE_THREAD_STACK_SIZE];
 
 
-#if defined(RT_USING_SMP) || defined(RT_USING_SMART)
-#ifndef SYSTEM_THREAD_STACK_SIZE
-#define SYSTEM_THREAD_STACK_SIZE IDLE_THREAD_STACK_SIZE
-#endif
-static struct rt_thread rt_system_thread;
-rt_align(RT_ALIGN_SIZE)
-static rt_uint8_t rt_system_stack[SYSTEM_THREAD_STACK_SIZE];
-static struct rt_semaphore system_sem;
-#endif
-
 #ifdef RT_USING_IDLE_HOOK
 #ifdef RT_USING_IDLE_HOOK
 #ifndef RT_IDLE_HOOK_LIST_SIZE
 #ifndef RT_IDLE_HOOK_LIST_SIZE
 #define RT_IDLE_HOOK_LIST_SIZE  4
 #define RT_IDLE_HOOK_LIST_SIZE  4
@@ -135,128 +123,6 @@ rt_err_t rt_thread_idle_delhook(void (*hook)(void))
 
 
 #endif /* RT_USING_IDLE_HOOK */
 #endif /* RT_USING_IDLE_HOOK */
 
 
-/**
- * @brief Enqueue a thread to defunct queue.
- *
- * @param thread the thread to be enqueued.
- *
- * @note It must be called between rt_hw_interrupt_disable and rt_hw_interrupt_enable
- */
-void rt_thread_defunct_enqueue(rt_thread_t thread)
-{
-    rt_base_t level;
-    level = rt_spin_lock_irqsave(&_defunct_spinlock);
-    rt_list_insert_after(&_rt_thread_defunct, &RT_THREAD_LIST_NODE(thread));
-    rt_spin_unlock_irqrestore(&_defunct_spinlock, level);
-#if defined(RT_USING_SMP) || defined(RT_USING_SMART)
-    rt_sem_release(&system_sem);
-#endif
-}
-
-/**
- * @brief Dequeue a thread from defunct queue.
- */
-rt_thread_t rt_thread_defunct_dequeue(void)
-{
-    rt_base_t level;
-    rt_thread_t thread = RT_NULL;
-    rt_list_t *l = &_rt_thread_defunct;
-
-#ifdef RT_USING_SMP
-    level = rt_spin_lock_irqsave(&_defunct_spinlock);
-    if (l->next != l)
-    {
-        thread = RT_THREAD_LIST_NODE_ENTRY(l->next);
-        rt_list_remove(&RT_THREAD_LIST_NODE(thread));
-    }
-    rt_spin_unlock_irqrestore(&_defunct_spinlock, level);
-#else
-    if (l->next != l)
-    {
-        thread = RT_THREAD_LIST_NODE_ENTRY(l->next);
-        level = rt_hw_interrupt_disable();
-        rt_list_remove(&RT_THREAD_LIST_NODE(thread));
-        rt_hw_interrupt_enable(level);
-    }
-#endif
-    return thread;
-}
-
-/**
- * @brief This function will perform system background job when system idle.
- */
-static void rt_defunct_execute(void)
-{
-    /* Loop until there is no dead thread. So one call to rt_defunct_execute
-     * will do all the cleanups. */
-    while (1)
-    {
-        rt_thread_t thread;
-        rt_bool_t object_is_systemobject;
-        void (*cleanup)(struct rt_thread *tid);
-
-#ifdef RT_USING_MODULE
-        struct rt_dlmodule *module = RT_NULL;
-#endif
-        /* get defunct thread */
-        thread = rt_thread_defunct_dequeue();
-        if (thread == RT_NULL)
-        {
-            break;
-        }
-
-#ifdef RT_USING_MODULE
-        module = (struct rt_dlmodule*)thread->parent.module_id;
-        if (module)
-        {
-            dlmodule_destroy(module);
-        }
-#endif
-
-#ifdef RT_USING_SIGNALS
-        rt_thread_free_sig(thread);
-#endif
-
-        /* store the point of "thread->cleanup" avoid to lose */
-        cleanup = thread->cleanup;
-
-        /* if it's a system object, detach it */
-        object_is_systemobject = rt_object_is_systemobject((rt_object_t)thread);
-        if (object_is_systemobject == RT_TRUE)
-        {
-            /* detach this object */
-            rt_object_detach((rt_object_t)thread);
-        }
-
-        /* invoke thread cleanup */
-        if (cleanup != RT_NULL)
-        {
-            cleanup(thread);
-        }
-
-#ifdef RT_USING_HEAP
-#ifdef RT_USING_MEM_PROTECTION
-        if (thread->mem_regions != RT_NULL)
-        {
-            RT_KERNEL_FREE(thread->mem_regions);
-        }
-#endif
-        /* if need free, delete it */
-        if (object_is_systemobject == RT_FALSE)
-        {
-            /* release thread's stack */
-#ifdef RT_USING_HW_STACK_GUARD
-            RT_KERNEL_FREE(thread->stack_buf);
-#else
-            RT_KERNEL_FREE(thread->stack_addr);
-#endif
-            /* delete thread object */
-            rt_object_delete((rt_object_t)thread);
-        }
-#endif
-    }
-}
-
 static void idle_thread_entry(void *parameter)
 static void idle_thread_entry(void *parameter)
 {
 {
     RT_UNUSED(parameter);
     RT_UNUSED(parameter);
@@ -286,10 +152,6 @@ static void idle_thread_entry(void *parameter)
         }
         }
 #endif /* RT_USING_IDLE_HOOK */
 #endif /* RT_USING_IDLE_HOOK */
 
 
-#if !defined(RT_USING_SMP) && !defined(RT_USING_SMART)
-        rt_defunct_execute();
-#endif /* RT_USING_SMP */
-
 #ifdef RT_USING_PM
 #ifdef RT_USING_PM
         void rt_system_power_manager(void);
         void rt_system_power_manager(void);
         rt_system_power_manager();
         rt_system_power_manager();
@@ -297,24 +159,6 @@ static void idle_thread_entry(void *parameter)
     }
     }
 }
 }
 
 
-#if defined(RT_USING_SMP) || defined(RT_USING_SMART)
-static void rt_thread_system_entry(void *parameter)
-{
-    RT_UNUSED(parameter);
-
-    while (1)
-    {
-        int ret = rt_sem_take(&system_sem, RT_WAITING_FOREVER);
-        if (ret != RT_EOK)
-        {
-            rt_kprintf("failed to sem_take() error %d\n", ret);
-            RT_ASSERT(0);
-        }
-        rt_defunct_execute();
-    }
-}
-#endif
-
 /**
 /**
  * @brief This function will initialize idle thread, then start it.
  * @brief This function will initialize idle thread, then start it.
  *
  *
@@ -327,6 +171,8 @@ void rt_thread_idle_init(void)
     char idle_thread_name[RT_NAME_MAX];
     char idle_thread_name[RT_NAME_MAX];
 #endif /* RT_NAME_MAX > 0 */
 #endif /* RT_NAME_MAX > 0 */
 
 
+    rt_spin_lock_init(&_hook_spinlock);
+
     for (i = 0; i < _CPUS_NR; i++)
     for (i = 0; i < _CPUS_NR; i++)
     {
     {
 #if RT_NAME_MAX > 0
 #if RT_NAME_MAX > 0
@@ -354,27 +200,6 @@ void rt_thread_idle_init(void)
         /* startup */
         /* startup */
         rt_thread_startup(&idle_thread[i]);
         rt_thread_startup(&idle_thread[i]);
     }
     }
-
-#if defined(RT_USING_SMP) || defined(RT_USING_SMART)
-    RT_ASSERT(RT_THREAD_PRIORITY_MAX > 2);
-
-    rt_spin_lock_init(&_defunct_spinlock);
-    rt_spin_lock_init(&_hook_spinlock);
-
-    rt_sem_init(&system_sem, "defunct", 0, RT_IPC_FLAG_FIFO);
-
-    /* create defunct thread */
-    rt_thread_init(&rt_system_thread,
-            "tsystem",
-            rt_thread_system_entry,
-            RT_NULL,
-            rt_system_stack,
-            sizeof(rt_system_stack),
-            RT_THREAD_PRIORITY_MAX - 2,
-            32);
-    /* startup */
-    rt_thread_startup(&rt_system_thread);
-#endif
 }
 }
 
 
 /**
 /**