diff --git a/src/idle.c b/src/idle.c index 99db64f571c0523b67c0d9b31409a66d346a3a29..aa14552a49f2ddb9306140bfe714c1a9781bd0ab 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 ce03ae25e9a4bc0586ab7a979136a209d2c9a0b1..0db9dd8e4d0219fc918520976aff93d5dd576659 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); } @@ -347,14 +373,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); } @@ -449,6 +476,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));