summaryrefslogtreecommitdiff
path: root/src/idle.c
diff options
context:
space:
mode:
authorousugo <[email protected]>2021-12-14 10:42:18 +0800
committerousugo <[email protected]>2021-12-14 10:42:18 +0800
commit4820dbb0b3a15a62f4cd5f3e20fb4e02e4bfbb20 (patch)
tree27698aa9180b0c25dd9c4d9ced3320da10360b1d /src/idle.c
parenta237f805b940db16ef0d0009e56eb183f5713c07 (diff)
parentc5208a7d19871573dcb719358d34d3effa0682e9 (diff)
Merge branch 'master' into addAnnotation
Diffstat (limited to 'src/idle.c')
-rw-r--r--src/idle.c67
1 files changed, 21 insertions, 46 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);