From f31d0cca716566a36cfef4c0ea7fc76c923a3422 Mon Sep 17 00:00:00 2001 From: shaojinchun Date: Thu, 18 Mar 2021 23:07:34 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E5=90=8C=E6=AD=A5=E4=B8=BB=E5=88=86?= =?UTF-8?q?=E6=94=AFcleanup=E7=A7=BB=E5=88=B0=E5=BD=93=E5=89=8D=E7=BA=BF?= =?UTF-8?q?=E7=A8=8B=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/idle.c | 79 +++++++++++----------------------------------------- src/thread.c | 37 +++++++++++++++++++++--- 2 files changed, 50 insertions(+), 66 deletions(-) diff --git a/src/idle.c b/src/idle.c index 42b2bb7ff0..a577999084 100644 --- a/src/idle.c +++ b/src/idle.c @@ -150,82 +150,37 @@ void rt_thread_idle_excute(void) { /* Loop until there is no dead thread. So one call to rt_thread_idle_excute * will do all the cleanups. */ - while (_has_defunct_thread()) + /* disable interrupt */ + + RT_DEBUG_NOT_IN_INTERRUPT; + +#ifdef RT_USING_HEAP + while (1) { rt_base_t lock; rt_thread_t thread; -#ifdef RT_USING_MODULE - struct rt_dlmodule *module = RT_NULL; -#endif - RT_DEBUG_NOT_IN_INTERRUPT; - /* disable interrupt */ lock = rt_hw_interrupt_disable(); - /* re-check whether list is empty */ - if (_has_defunct_thread()) - { - /* 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); - } -#endif - /* remove defunct thread */ - rt_list_remove(&(thread->tlist)); - - /* lock scheduler to prevent scheduling in cleanup function. */ - rt_enter_critical(); - - /* invoke thread cleanup */ - if (thread->cleanup != RT_NULL) - thread->cleanup(thread); - -#ifdef RT_USING_SIGNALS - rt_thread_free_sig(thread); -#endif - - /* if it's a system object, not delete it */ - if (rt_object_is_systemobject((rt_object_t)thread) == RT_TRUE) - { - /* detach this object */ - rt_object_detach((rt_object_t)thread); - /* unlock scheduler */ - rt_exit_critical(); - - /* enable interrupt */ - rt_hw_interrupt_enable(lock); - - return; - } - - /* unlock scheduler */ - rt_exit_critical(); - } - else + /* check whether list is empty */ + if (!_has_defunct_thread()) { - /* enable interrupt */ rt_hw_interrupt_enable(lock); - - /* may the defunct thread list is removed by others, just return */ - return; + break; } - - /* enable interrupt */ - rt_hw_interrupt_enable(lock); - -#ifdef RT_USING_HEAP + /* get defunct thread */ + thread = rt_list_entry(rt_thread_defunct.next, + struct rt_thread, + tlist); + /* remove defunct thread */ + rt_list_remove(&(thread->tlist)); /* release thread's stack */ RT_KERNEL_FREE(thread->stack_addr); /* delete thread object */ rt_object_delete((rt_object_t)thread); -#endif + rt_hw_interrupt_enable(lock); } +#endif } extern void rt_system_power_manager(void); diff --git a/src/thread.c b/src/thread.c index dc497ee657..2cf3cfb905 100644 --- a/src/thread.c +++ b/src/thread.c @@ -77,6 +77,31 @@ void rt_thread_inited_sethook(void (*hook)(rt_thread_t thread)) #endif +/* must be invoke witch rt_hw_interrupt_disable */ +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 + level = rt_hw_interrupt_disable(); +#ifdef RT_USING_MODULE + module = (struct rt_dlmodule*)thread->module_id; + if (module) + { + dlmodule_destroy(module); + } +#endif + /* invoke thread cleanup */ + if (thread->cleanup != RT_NULL) + thread->cleanup(thread); + +#ifdef RT_USING_SIGNALS + rt_thread_free_sig(thread); +#endif + rt_hw_interrupt_enable(level); +} + void rt_thread_exit(void) { struct rt_thread *thread; @@ -88,6 +113,8 @@ void rt_thread_exit(void) /* disable interrupt */ level = rt_hw_interrupt_disable(); + _thread_cleanup_execute(thread); + /* remove from schedule */ rt_schedule_remove_thread(thread); /* change stat */ @@ -96,8 +123,7 @@ void rt_thread_exit(void) /* remove it from timer list */ rt_timer_detach(&thread->thread_timer); - if ((rt_object_is_systemobject((rt_object_t)thread) == RT_TRUE) && - thread->cleanup == RT_NULL) + if (rt_object_is_systemobject((rt_object_t)thread) == RT_TRUE) { rt_object_detach((rt_object_t)thread); } @@ -357,14 +383,15 @@ rt_err_t rt_thread_detach(rt_thread_t thread) rt_schedule_remove_thread(thread); } + _thread_cleanup_execute(thread); + /* release thread timer */ rt_timer_detach(&(thread->thread_timer)); /* change stat */ thread->stat = RT_THREAD_CLOSE; - if ((rt_object_is_systemobject((rt_object_t)thread) == RT_TRUE) && - thread->cleanup == RT_NULL) + if (rt_object_is_systemobject((rt_object_t)thread) == RT_TRUE) { rt_object_detach((rt_object_t)thread); } @@ -459,6 +486,8 @@ rt_err_t rt_thread_delete(rt_thread_t thread) rt_schedule_remove_thread(thread); } + _thread_cleanup_execute(thread); + /* release thread timer */ rt_timer_detach(&(thread->thread_timer)); -- Gitee From 8759075997ef2e7140d74367e632ebb8a140ffe2 Mon Sep 17 00:00:00 2001 From: shaojinchun Date: Fri, 19 Mar 2021 09:52:06 +0800 Subject: [PATCH 2/2] =?UTF-8?q?smp=E5=8A=A0=E5=85=A5reclaim=E7=BA=BF?= =?UTF-8?q?=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/rtthread.h | 5 ++++- src/idle.c | 53 +++++++++++++++++++++++++++++++++++++++++----- src/thread.c | 12 +++++++++++ 3 files changed, 64 insertions(+), 6 deletions(-) diff --git a/include/rtthread.h b/include/rtthread.h index a72d2d30c8..f83f414f0d 100644 --- a/include/rtthread.h +++ b/include/rtthread.h @@ -182,8 +182,11 @@ void rt_thread_idle_init(void); rt_err_t rt_thread_idle_sethook(void (*hook)(void)); rt_err_t rt_thread_idle_delhook(void (*hook)(void)); #endif -void rt_thread_idle_excute(void); +void rt_thread_reclaim_execute(void); rt_thread_t rt_thread_idle_gethandler(void); +#ifdef RT_USING_SMP +void rt_wakeup_reclaim_thread(void); +#endif /* * schedule service diff --git a/src/idle.c b/src/idle.c index a577999084..028fbb2894 100644 --- a/src/idle.c +++ b/src/idle.c @@ -50,6 +50,12 @@ static struct rt_thread idle[_CPUS_NR]; ALIGN(RT_ALIGN_SIZE) static rt_uint8_t rt_thread_stack[_CPUS_NR][IDLE_THREAD_STACK_SIZE]; +#ifdef RT_USING_SMP +static struct rt_thread rt_reclaim_thread; +static rt_uint8_t rt_reclaim_stack[IDLE_THREAD_STACK_SIZE]; +static struct rt_semaphore reclaim_sem; +#endif + #ifdef RT_USING_IDLE_HOOK #ifndef RT_IDLE_HOOK_LIST_SIZE #define RT_IDLE_HOOK_LIST_SIZE 4 @@ -132,7 +138,7 @@ rt_inline int _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_idle_excute thus optimize the "while" loop + * not change within rt_thread_reclaim_exceute thus optimize the "while" loop * into a "if". * * So add the volatile qualifier here. */ @@ -146,9 +152,9 @@ rt_inline int _has_defunct_thread(void) * * This function will perform system background job when system idle. */ -void rt_thread_idle_excute(void) +void rt_thread_reclaim_execute(void) { - /* Loop until there is no dead thread. So one call to rt_thread_idle_excute + /* Loop until there is no dead thread. So one call to rt_thread_reclaim_execute * will do all the cleanups. */ /* disable interrupt */ @@ -210,13 +216,32 @@ static void rt_thread_idle_entry(void *parameter) } #endif - rt_thread_idle_excute(); -#ifdef RT_USING_PM +#ifndef RT_USING_SMP + rt_thread_reclaim_execute(); +#endif + +#ifdef RT_USING_PM rt_system_power_manager(); #endif } } +#ifdef RT_USING_SMP +void rt_wakeup_reclaim_thread(void) +{ + rt_sem_release(&reclaim_sem); +} + +static void rt_thread_reclaim_entry(void *parameter) +{ + while (1) + { + rt_sem_take(&reclaim_sem, RT_WAITING_FOREVER); + rt_thread_reclaim_execute(); + } +} +#endif + /** * @ingroup SystemInit * @@ -246,6 +271,24 @@ void rt_thread_idle_init(void) /* startup */ rt_thread_startup(&idle[i]); } + +#ifdef RT_USING_SMP + RT_ASSERT(RT_THREAD_PRIORITY_MAX > 2); + + rt_sem_init(&reclaim_sem, "reclaim", 1, RT_IPC_FLAG_FIFO); + + /* create defunct thread */ + rt_thread_init(&rt_reclaim_thread, + "reclaim", + rt_thread_reclaim_entry, + RT_NULL, + rt_reclaim_stack, + sizeof(rt_reclaim_stack), + RT_THREAD_PRIORITY_MAX - 2, + 32); + /* startup */ + rt_thread_startup(&rt_reclaim_thread); +#endif } /** diff --git a/src/thread.c b/src/thread.c index 2cf3cfb905..546e9c2fcf 100644 --- a/src/thread.c +++ b/src/thread.c @@ -94,7 +94,9 @@ static void _thread_cleanup_execute(rt_thread_t thread) #endif /* invoke thread cleanup */ if (thread->cleanup != RT_NULL) + { thread->cleanup(thread); + } #ifdef RT_USING_SIGNALS rt_thread_free_sig(thread); @@ -131,6 +133,9 @@ void rt_thread_exit(void) { /* insert to defunct thread list */ rt_list_insert_after(&rt_thread_defunct, &(thread->tlist)); +#ifdef RT_USING_SMP + rt_wakeup_reclaim_thread(); +#endif } /* switch to next task */ @@ -401,6 +406,9 @@ rt_err_t rt_thread_detach(rt_thread_t thread) lock = rt_hw_interrupt_disable(); /* insert to defunct thread list */ rt_list_insert_after(&rt_thread_defunct, &(thread->tlist)); +#ifdef RT_USING_SMP + rt_wakeup_reclaim_thread(); +#endif /* enable interrupt */ rt_hw_interrupt_enable(lock); } @@ -500,6 +508,10 @@ rt_err_t rt_thread_delete(rt_thread_t thread) /* insert to defunct thread list */ rt_list_insert_after(&rt_thread_defunct, &(thread->tlist)); +#ifdef RT_USING_SMP + rt_wakeup_reclaim_thread(); +#endif + /* enable interrupt */ rt_hw_interrupt_enable(lock); -- Gitee