summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorthewon86 <[email protected]>2021-11-26 09:13:18 +0800
committerthewon86 <[email protected]>2021-11-26 09:13:18 +0800
commit5ae6b54e21d49d793178359e169014fe74ac3487 (patch)
tree52f9b933811c862f2ae75af4d54ac2df3c823fa4
parent5711b0a76b8d80ab2dc4cdbf925a7b48f4140a5d (diff)
remove duplicate work between idle and thread_exit
-rw-r--r--src/idle.c67
-rw-r--r--src/thread.c74
2 files changed, 38 insertions, 103 deletions
diff --git a/src/idle.c b/src/idle.c
index 61f6a5b383..f1db468e26 100644
--- a/src/idle.c
+++ b/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);
diff --git a/src/thread.c b/src/thread.c
index ab5264053e..b8f4535647 100644
--- a/src/thread.c
+++ b/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;