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 @@ -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 6256deaf82..7913e12f5d 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 @@ -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;