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

Merge pull request #5278 from thewon86/master

remove duplicate work between idle and thread_exit
......@@ -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);
......
......@@ -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>
......@@ -74,30 +75,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;
......@@ -109,31 +86,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,
......@@ -383,7 +352,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));
......@@ -391,19 +361,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;
}
......@@ -493,14 +455,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;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册