diff --git a/include/rtthread.h b/include/rtthread.h index 0e98753c6f669e78b352fefe2b427ae2f8632b53..dbb9879af3a5ec97b648fe60658ed5458b783d6e 100644 --- a/include/rtthread.h +++ b/include/rtthread.h @@ -120,6 +120,7 @@ void rt_thread_idle_init(void); #ifdef RT_USING_HOOK void rt_thread_idle_sethook(void (*hook)(void)); #endif +void rt_thread_idle_excute(void); /* * schedule service diff --git a/src/idle.c b/src/idle.c index f750a816015549582d3f71d9c4dc0081c3377570..fcd6e457e2fb4b3463e263c6a80ff32b79911c28 100644 --- a/src/idle.c +++ b/src/idle.c @@ -52,61 +52,88 @@ void rt_thread_idle_sethook(void (*hook)()) /*@}*/ #endif -static void rt_thread_idle_entry(void* parameter) +/** + * This function will do some things when system idle. + */ +void rt_thread_idle_excute(void) { - while (1) +#ifdef RT_USING_HEAP + /* check the defunct thread list */ + if (!rt_list_isempty(&rt_thread_defunct)) { -#ifdef RT_USING_HOOK - /* if there is an idle thread hook */ - if (rt_thread_idle_hook != RT_NULL) rt_thread_idle_hook(); + rt_base_t lock; + rt_thread_t thread; +#ifdef RT_USING_MODULE + rt_module_t module; #endif -#ifdef RT_USING_HEAP - /* check the defunct thread list */ + /* disable interrupt */ + lock = rt_hw_interrupt_disable(); + + /* re-check whether list is empty */ if (!rt_list_isempty(&rt_thread_defunct)) { - rt_base_t lock; - struct rt_thread* thread = rt_list_entry(rt_thread_defunct.next, struct rt_thread, tlist); + /* get defunct thread */ + thread = rt_list_entry(rt_thread_defunct.next, struct rt_thread, tlist); + + /* get thread's parent module */ #ifdef RT_USING_MODULE - rt_module_t module = thread->module_parent; + module = thread->module_parent; #endif - - /* disable interrupt */ - lock = rt_hw_interrupt_disable(); - + /* remove defunct thread */ rt_list_remove(&(thread->tlist)); - + } + else + { /* enable interrupt */ rt_hw_interrupt_enable(lock); - /* release thread's stack */ - rt_free(thread->stack_addr); + /* may the defunct thread list is removed by others, just return */ + return; + } - /* delete thread object */ - rt_object_delete((rt_object_t)thread); + /* enable interrupt */ + rt_hw_interrupt_enable(lock); #ifdef RT_USING_MODULE - if(module != RT_NULL) + if(module != RT_NULL) + { + /* if the thread is module's main thread */ + if(module->module_thread == thread) { - /* if the thread is module's main thread */ - if(module->module_thread == thread) - { - /* detach module's main thread */ - module->module_thread = RT_NULL; - } - - /* if sub thread list and main thread are null */ - if((module->module_thread == RT_NULL) && - rt_list_isempty(&module->module_object[RT_Object_Class_Thread].object_list) && - (module->module_info->module_type == RT_Module_Class_APP)) - { - /* unload module */ - rt_module_unload(module); - } - } + /* detach module's main thread */ + module->module_thread = RT_NULL; + } + + /* if sub thread list and main thread are null */ + if((module->module_thread == RT_NULL) && + rt_list_isempty(&module->module_object[RT_Object_Class_Thread].object_list) && + (module->module_info->module_type == RT_Module_Class_APP)) + { + /* unload module */ + rt_module_unload(module); + } + } #endif - } + /* release thread's stack */ + rt_free(thread->stack_addr); + + /* delete thread object */ + rt_object_delete((rt_object_t)thread); + } +#endif +} + +static void rt_thread_idle_entry(void* parameter) +{ + while (1) + { +#ifdef RT_USING_HOOK + /* if there is an idle thread hook */ + if (rt_thread_idle_hook != RT_NULL) rt_thread_idle_hook(); #endif + + rt_thread_idle_excute(); } }