summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/components.c3
-rw-r--r--src/defunct.c171
-rw-r--r--src/idle.c179
3 files changed, 176 insertions, 177 deletions
diff --git a/src/components.c b/src/components.c
index d1adac181b..b561e227de 100644
--- a/src/components.c
+++ b/src/components.c
@@ -270,6 +270,9 @@ int rtthread_startup(void)
/* idle thread initialization */
rt_thread_idle_init();
+ /* defunct thread initialization */
+ rt_thread_defunct_init();
+
#ifdef RT_USING_SMP
rt_hw_spin_lock(&_cpus_lock);
#endif /* RT_USING_SMP */
diff --git a/src/defunct.c b/src/defunct.c
new file mode 100644
index 0000000000..7fae3a876c
--- /dev/null
+++ b/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);
+}
diff --git a/src/idle.c b/src/idle.c
index 092b273783..9a805737eb 100644
--- a/src/idle.c
+++ b/src/idle.c
@@ -44,22 +44,10 @@
#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];
rt_align(RT_ALIGN_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
#ifndef RT_IDLE_HOOK_LIST_SIZE
#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 */
-/**
- * @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)
{
RT_UNUSED(parameter);
@@ -286,10 +152,6 @@ static void idle_thread_entry(void *parameter)
}
#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
void rt_system_power_manager(void);
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.
*
@@ -327,6 +171,8 @@ void rt_thread_idle_init(void)
char idle_thread_name[RT_NAME_MAX];
#endif /* RT_NAME_MAX > 0 */
+ rt_spin_lock_init(&_hook_spinlock);
+
for (i = 0; i < _CPUS_NR; i++)
{
#if RT_NAME_MAX > 0
@@ -354,27 +200,6 @@ void rt_thread_idle_init(void)
/* startup */
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
}
/**