未验证 提交 1e03864f 编写于 作者: G guo 提交者: GitHub

Merge pull request #5278 from thewon86/master

remove duplicate work between idle and thread_exit
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
* 2018-07-14 armink add idle hook list * 2018-07-14 armink add idle hook list
* 2018-11-22 Jesven add per cpu idle task * 2018-11-22 Jesven add per cpu idle task
* combine the code of primary and secondary cpu * combine the code of primary and secondary cpu
* 2021-11-15 THEWON Remove duplicate work between idle and _thread_exit
*/ */
#include <rthw.h> #include <rthw.h>
...@@ -136,22 +137,6 @@ rt_err_t rt_thread_idle_delhook(void (*hook)(void)) ...@@ -136,22 +137,6 @@ rt_err_t rt_thread_idle_delhook(void (*hook)(void))
#endif /* RT_USING_IDLE_HOOK */ #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. * @brief Enqueue a thread to defunct queue.
* *
...@@ -167,14 +152,16 @@ void rt_thread_defunct_enqueue(rt_thread_t thread) ...@@ -167,14 +152,16 @@ void rt_thread_defunct_enqueue(rt_thread_t thread)
/** /**
* @brief Dequeue a thread from defunct queue. * @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) rt_thread_t rt_thread_defunct_dequeue(void)
{ {
register rt_base_t lock;
rt_thread_t thread = RT_NULL; rt_thread_t thread = RT_NULL;
rt_list_t *l = &_rt_thread_defunct; rt_list_t *l = &_rt_thread_defunct;
#ifdef RT_USING_SMP
/* disable interrupt */
lock = rt_hw_interrupt_disable();
if (l->next != l) if (l->next != l)
{ {
thread = rt_list_entry(l->next, thread = rt_list_entry(l->next,
...@@ -182,6 +169,18 @@ rt_thread_t rt_thread_defunct_dequeue(void) ...@@ -182,6 +169,18 @@ rt_thread_t rt_thread_defunct_dequeue(void)
tlist); tlist);
rt_list_remove(&(thread->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; return thread;
} }
...@@ -194,51 +193,30 @@ static void rt_defunct_execute(void) ...@@ -194,51 +193,30 @@ static void rt_defunct_execute(void)
* will do all the cleanups. */ * will do all the cleanups. */
while (1) while (1)
{ {
rt_base_t lock;
rt_thread_t thread; rt_thread_t thread;
void (*cleanup)(struct rt_thread *tid); void (*cleanup)(struct rt_thread *tid);
#ifdef RT_USING_MODULE #ifdef RT_USING_MODULE
struct rt_dlmodule *module = RT_NULL; struct rt_dlmodule *module = RT_NULL;
#endif #endif
RT_DEBUG_NOT_IN_INTERRUPT; /* get defunct thread */
thread = rt_thread_defunct_dequeue();
/* disable interrupt */ if (thread == RT_NULL)
lock = rt_hw_interrupt_disable();
#ifdef RT_USING_MODULE
/* check whether list is empty */
if (!_idle_has_defunct_thread())
{ {
rt_hw_interrupt_enable(lock);
break; break;
} }
/* get defunct thread */ #ifdef RT_USING_MODULE
thread = rt_list_entry(_rt_thread_defunct.next,
struct rt_thread,
tlist);
module = (struct rt_dlmodule*)thread->module_id; module = (struct rt_dlmodule*)thread->module_id;
if (module) if (module)
{ {
dlmodule_destroy(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 #endif
/* invoke thread cleanup */ /* invoke thread cleanup */
cleanup = thread->cleanup; cleanup = thread->cleanup;
if (cleanup != RT_NULL) if (cleanup != RT_NULL)
{ {
rt_hw_interrupt_enable(lock);
cleanup(thread); cleanup(thread);
lock = rt_hw_interrupt_disable();
} }
#ifdef RT_USING_SIGNALS #ifdef RT_USING_SIGNALS
...@@ -250,12 +228,9 @@ static void rt_defunct_execute(void) ...@@ -250,12 +228,9 @@ static void rt_defunct_execute(void)
{ {
/* detach this object */ /* detach this object */
rt_object_detach((rt_object_t)thread); rt_object_detach((rt_object_t)thread);
/* enable interrupt */
rt_hw_interrupt_enable(lock);
} }
else else
{ {
rt_hw_interrupt_enable(lock);
#ifdef RT_USING_HEAP #ifdef RT_USING_HEAP
/* release thread's stack */ /* release thread's stack */
RT_KERNEL_FREE(thread->stack_addr); RT_KERNEL_FREE(thread->stack_addr);
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
* 2018-11-22 Jesven yield is same to rt_schedule * 2018-11-22 Jesven yield is same to rt_schedule
* add support for tasks bound to cpu * add support for tasks bound to cpu
* 2021-02-24 Meco Man rearrange rt_thread_control() - schedule the thread when close it * 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> #include <rthw.h>
...@@ -74,30 +75,6 @@ void rt_thread_inited_sethook(void (*hook)(rt_thread_t thread)) ...@@ -74,30 +75,6 @@ void rt_thread_inited_sethook(void (*hook)(rt_thread_t thread))
#endif /* RT_USING_HOOK */ #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) static void _thread_exit(void)
{ {
struct rt_thread *thread; struct rt_thread *thread;
...@@ -109,31 +86,23 @@ static void _thread_exit(void) ...@@ -109,31 +86,23 @@ static void _thread_exit(void)
/* disable interrupt */ /* disable interrupt */
level = rt_hw_interrupt_disable(); level = rt_hw_interrupt_disable();
_thread_cleanup_execute(thread);
/* remove from schedule */ /* remove from schedule */
rt_schedule_remove_thread(thread); rt_schedule_remove_thread(thread);
/* change stat */
thread->stat = RT_THREAD_CLOSE;
/* remove it from timer list */ /* remove it from timer list */
rt_timer_detach(&thread->thread_timer); rt_timer_detach(&thread->thread_timer);
if (rt_object_is_systemobject((rt_object_t)thread) == RT_TRUE) /* change stat */
{ thread->stat = RT_THREAD_CLOSE;
rt_object_detach((rt_object_t)thread);
}
else
{
/* insert to defunct thread list */
rt_thread_defunct_enqueue(thread);
}
/* switch to next task */ /* insert to defunct thread list */
rt_schedule(); rt_thread_defunct_enqueue(thread);
/* enable interrupt */ /* enable interrupt */
rt_hw_interrupt_enable(level); rt_hw_interrupt_enable(level);
/* switch to next task */
rt_schedule();
} }
static rt_err_t _thread_init(struct rt_thread *thread, static rt_err_t _thread_init(struct rt_thread *thread,
...@@ -383,7 +352,8 @@ rt_err_t rt_thread_detach(rt_thread_t thread) ...@@ -383,7 +352,8 @@ rt_err_t rt_thread_detach(rt_thread_t thread)
rt_schedule_remove_thread(thread); rt_schedule_remove_thread(thread);
} }
_thread_cleanup_execute(thread); /* disable interrupt */
lock = rt_hw_interrupt_disable();
/* release thread timer */ /* release thread timer */
rt_timer_detach(&(thread->thread_timer)); rt_timer_detach(&(thread->thread_timer));
...@@ -391,19 +361,11 @@ rt_err_t rt_thread_detach(rt_thread_t thread) ...@@ -391,19 +361,11 @@ rt_err_t rt_thread_detach(rt_thread_t thread)
/* change stat */ /* change stat */
thread->stat = RT_THREAD_CLOSE; thread->stat = RT_THREAD_CLOSE;
if (rt_object_is_systemobject((rt_object_t)thread) == RT_TRUE) /* insert to defunct thread list */
{ rt_thread_defunct_enqueue(thread);
rt_object_detach((rt_object_t)thread);
} /* enable interrupt */
else rt_hw_interrupt_enable(lock);
{
/* disable interrupt */
lock = rt_hw_interrupt_disable();
/* insert to defunct thread list */
rt_thread_defunct_enqueue(thread);
/* enable interrupt */
rt_hw_interrupt_enable(lock);
}
return RT_EOK; return RT_EOK;
} }
...@@ -493,14 +455,12 @@ rt_err_t rt_thread_delete(rt_thread_t thread) ...@@ -493,14 +455,12 @@ rt_err_t rt_thread_delete(rt_thread_t thread)
rt_schedule_remove_thread(thread); rt_schedule_remove_thread(thread);
} }
_thread_cleanup_execute(thread); /* disable interrupt */
lock = rt_hw_interrupt_disable();
/* release thread timer */ /* release thread timer */
rt_timer_detach(&(thread->thread_timer)); rt_timer_detach(&(thread->thread_timer));
/* disable interrupt */
lock = rt_hw_interrupt_disable();
/* change stat */ /* change stat */
thread->stat = RT_THREAD_CLOSE; thread->stat = RT_THREAD_CLOSE;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册