From 3ed84b8d03dc9778f1c262278e2b8653de834408 Mon Sep 17 00:00:00 2001 From: shaojinchun Date: Fri, 24 Jul 2020 21:13:56 +0800 Subject: 解决yield操作不能及时释放cpu的问题 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/thread.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/thread.c') diff --git a/src/thread.c b/src/thread.c index 715596b132..60aa17f381 100644 --- a/src/thread.c +++ b/src/thread.c @@ -478,7 +478,15 @@ RTM_EXPORT(rt_thread_delete); */ rt_err_t rt_thread_yield(void) { + struct rt_thread *thread; + rt_base_t lock; + + thread = rt_thread_self(); + lock = rt_hw_interrupt_disable(); + thread->remaining_tick = thread->init_tick; + thread->stat |= RT_THREAD_STAT_YIELD; rt_schedule(); + rt_hw_interrupt_enable(lock); return RT_EOK; } -- cgit v1.3.1 From c15a7858c9a7bc1f978faa5f0ea3f618fbd3bc03 Mon Sep 17 00:00:00 2001 From: chenchaoqun Date: Fri, 14 Aug 2020 15:52:35 +0800 Subject: [fix] thread control bug about RT_THREAD_CTRL_CLOSE command --- src/thread.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'src/thread.c') diff --git a/src/thread.c b/src/thread.c index 715596b132..9f80482b20 100644 --- a/src/thread.c +++ b/src/thread.c @@ -679,9 +679,17 @@ rt_err_t rt_thread_control(rt_thread_t thread, int cmd, void *arg) case RT_THREAD_CTRL_STARTUP: return rt_thread_startup(thread); -#ifdef RT_USING_HEAP case RT_THREAD_CTRL_CLOSE: - return rt_thread_delete(thread); + + if (rt_object_is_systemobject((rt_object_t)thread) == RT_TRUE) + { + return rt_thread_detach(thread); + } +#ifdef RT_USING_HEAP + else + { + return rt_thread_delete(thread); + } #endif #ifdef RT_USING_SMP -- cgit v1.3.1 From 0776b36a4f17239740c0a4d0254330c0e5ff9824 Mon Sep 17 00:00:00 2001 From: Bernard Xiong Date: Thu, 22 Oct 2020 22:44:58 +0800 Subject: [Kernel] fix the delay_until issue --- src/thread.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/thread.c') diff --git a/src/thread.c b/src/thread.c index 7a90e57f25..49e2022bf7 100644 --- a/src/thread.c +++ b/src/thread.c @@ -569,7 +569,7 @@ rt_err_t rt_thread_delay_until(rt_tick_t *tick, rt_tick_t inc_tick) if (rt_tick_get() - *tick < inc_tick) { - *tick = rt_tick_get() - *tick + inc_tick; + *tick = *tick + inc_tick - rt_tick_get(); /* suspend thread */ rt_thread_suspend(thread); -- cgit v1.3.1 From b4e57db1a8c7bd99373c9859bdca252645b11e96 Mon Sep 17 00:00:00 2001 From: bernard Date: Thu, 31 Dec 2020 09:47:55 +0800 Subject: [kernel] Use object_find to implement thread_find/device_find --- src/device.c | 33 +-------------------------------- src/thread.c | 33 +-------------------------------- 2 files changed, 2 insertions(+), 64 deletions(-) (limited to 'src/thread.c') diff --git a/src/device.c b/src/device.c index 32c06b380c..a4f004fb69 100644 --- a/src/device.c +++ b/src/device.c @@ -111,38 +111,7 @@ rt_err_t rt_device_init_all(void) */ rt_device_t rt_device_find(const char *name) { - struct rt_object *object; - struct rt_list_node *node; - struct rt_object_information *information; - - /* enter critical */ - if (rt_thread_self() != RT_NULL) - rt_enter_critical(); - - /* try to find device object */ - information = rt_object_get_information(RT_Object_Class_Device); - RT_ASSERT(information != RT_NULL); - for (node = information->object_list.next; - node != &(information->object_list); - node = node->next) - { - object = rt_list_entry(node, struct rt_object, list); - if (rt_strncmp(object->name, name, RT_NAME_MAX) == 0) - { - /* leave critical */ - if (rt_thread_self() != RT_NULL) - rt_exit_critical(); - - return (rt_device_t)object; - } - } - - /* leave critical */ - if (rt_thread_self() != RT_NULL) - rt_exit_critical(); - - /* not found */ - return RT_NULL; + return (rt_device_t)rt_object_find(name, RT_Object_Class_Device); } RTM_EXPORT(rt_device_find); diff --git a/src/thread.c b/src/thread.c index 49e2022bf7..ce03ae25e9 100644 --- a/src/thread.c +++ b/src/thread.c @@ -862,38 +862,7 @@ RTM_EXPORT(rt_thread_timeout); */ rt_thread_t rt_thread_find(char *name) { - struct rt_object_information *information; - struct rt_object *object; - struct rt_list_node *node; - - /* enter critical */ - if (rt_thread_self() != RT_NULL) - rt_enter_critical(); - - /* try to find device object */ - information = rt_object_get_information(RT_Object_Class_Thread); - RT_ASSERT(information != RT_NULL); - for (node = information->object_list.next; - node != &(information->object_list); - node = node->next) - { - object = rt_list_entry(node, struct rt_object, list); - if (rt_strncmp(object->name, name, RT_NAME_MAX) == 0) - { - /* leave critical */ - if (rt_thread_self() != RT_NULL) - rt_exit_critical(); - - return (rt_thread_t)object; - } - } - - /* leave critical */ - if (rt_thread_self() != RT_NULL) - rt_exit_critical(); - - /* not found */ - return RT_NULL; + return (rt_thread_t)rt_object_find(name, RT_Object_Class_Thread); } RTM_EXPORT(rt_thread_find); -- cgit v1.3.1 From 5957e157545e48b30d8a3fef504024cb5482a76e Mon Sep 17 00:00:00 2001 From: shaojinchun Date: Thu, 31 Dec 2020 10:31:06 +0800 Subject: cleanup操作改由当前线程退出前执行 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(-) (limited to 'src/thread.c') diff --git a/src/idle.c b/src/idle.c index 99db64f571..aa14552a49 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 49e2022bf7..a4cd3e9dd1 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)); -- cgit v1.3.1 From 2b98ac215a4e07401464bfcd6ad00957ff03bd72 Mon Sep 17 00:00:00 2001 From: Meco Man <920369182@qq.com> Date: Wed, 24 Feb 2021 16:29:43 +0800 Subject: [kernel] rearrange rt_thread_control() - schedule the thread when close it --- components/libc/compilers/common/stdlib.c | 10 +-- src/thread.c | 141 ++++++++++++++++-------------- 2 files changed, 77 insertions(+), 74 deletions(-) (limited to 'src/thread.c') diff --git a/components/libc/compilers/common/stdlib.c b/components/libc/compilers/common/stdlib.c index 9f801ab966..48a86098cd 100644 --- a/components/libc/compilers/common/stdlib.c +++ b/components/libc/compilers/common/stdlib.c @@ -14,18 +14,10 @@ void __rt_libc_exit(int status) { rt_thread_t self = rt_thread_self(); -#ifdef RT_USING_MODULE - if (dlmodule_self()) - { - dlmodule_exit(status); - } -#endif - if (self != RT_NULL) { rt_kprintf("thread:%s exit:%d!\n", self->name, status); - rt_thread_suspend(self); - rt_schedule(); + rt_thread_control(self, RT_THREAD_CTRL_CLOSE, RT_NULL); } } diff --git a/src/thread.c b/src/thread.c index 0db9dd8e4d..2681eca59f 100644 --- a/src/thread.c +++ b/src/thread.c @@ -26,6 +26,7 @@ * bug when thread has not startup. * 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 */ #include @@ -670,83 +671,93 @@ rt_err_t rt_thread_control(rt_thread_t thread, int cmd, void *arg) switch (cmd) { - case RT_THREAD_CTRL_CHANGE_PRIORITY: - /* disable interrupt */ - temp = rt_hw_interrupt_disable(); - - /* for ready thread, change queue */ - if ((thread->stat & RT_THREAD_STAT_MASK) == RT_THREAD_READY) + case RT_THREAD_CTRL_CHANGE_PRIORITY: { - /* remove thread from schedule queue first */ - rt_schedule_remove_thread(thread); - - /* change thread priority */ - thread->current_priority = *(rt_uint8_t *)arg; - - /* recalculate priority attribute */ -#if RT_THREAD_PRIORITY_MAX > 32 - thread->number = thread->current_priority >> 3; /* 5bit */ - thread->number_mask = 1 << thread->number; - thread->high_mask = 1 << (thread->current_priority & 0x07); /* 3bit */ -#else - thread->number_mask = 1 << thread->current_priority; -#endif - - /* insert thread to schedule queue again */ - rt_schedule_insert_thread(thread); + /* disable interrupt */ + temp = rt_hw_interrupt_disable(); + + /* for ready thread, change queue */ + if ((thread->stat & RT_THREAD_STAT_MASK) == RT_THREAD_READY) + { + /* remove thread from schedule queue first */ + rt_schedule_remove_thread(thread); + + /* change thread priority */ + thread->current_priority = *(rt_uint8_t *)arg; + + /* recalculate priority attribute */ + #if RT_THREAD_PRIORITY_MAX > 32 + thread->number = thread->current_priority >> 3; /* 5bit */ + thread->number_mask = 1 << thread->number; + thread->high_mask = 1 << (thread->current_priority & 0x07); /* 3bit */ + #else + thread->number_mask = 1 << thread->current_priority; + #endif + + /* insert thread to schedule queue again */ + rt_schedule_insert_thread(thread); + } + else + { + thread->current_priority = *(rt_uint8_t *)arg; + + /* recalculate priority attribute */ + #if RT_THREAD_PRIORITY_MAX > 32 + thread->number = thread->current_priority >> 3; /* 5bit */ + thread->number_mask = 1 << thread->number; + thread->high_mask = 1 << (thread->current_priority & 0x07); /* 3bit */ + #else + thread->number_mask = 1 << thread->current_priority; + #endif + } + + /* enable interrupt */ + rt_hw_interrupt_enable(temp); + break; } - else - { - thread->current_priority = *(rt_uint8_t *)arg; - /* recalculate priority attribute */ -#if RT_THREAD_PRIORITY_MAX > 32 - thread->number = thread->current_priority >> 3; /* 5bit */ - thread->number_mask = 1 << thread->number; - thread->high_mask = 1 << (thread->current_priority & 0x07); /* 3bit */ -#else - thread->number_mask = 1 << thread->current_priority; -#endif + case RT_THREAD_CTRL_STARTUP: + { + return rt_thread_startup(thread); } - /* enable interrupt */ - rt_hw_interrupt_enable(temp); - break; - - case RT_THREAD_CTRL_STARTUP: - return rt_thread_startup(thread); - - case RT_THREAD_CTRL_CLOSE: - - if (rt_object_is_systemobject((rt_object_t)thread) == RT_TRUE) + case RT_THREAD_CTRL_CLOSE: { - return rt_thread_detach(thread); + rt_err_t rt_err; + + if (rt_object_is_systemobject((rt_object_t)thread) == RT_TRUE) + { + rt_err = rt_thread_detach(thread); + } + #ifdef RT_USING_HEAP + else + { + rt_err = rt_thread_delete(thread); + } + #endif + rt_schedule(); + return rt_err; } -#ifdef RT_USING_HEAP - else + + #ifdef RT_USING_SMP + case RT_THREAD_CTRL_BIND_CPU: { - return rt_thread_delete(thread); - } -#endif + rt_uint8_t cpu; -#ifdef RT_USING_SMP - case RT_THREAD_CTRL_BIND_CPU: - { - rt_uint8_t cpu; + if ((thread->stat & RT_THREAD_STAT_MASK) != RT_THREAD_INIT) + { + /* we only support bind cpu before started phase. */ + return RT_ERROR; + } - if ((thread->stat & RT_THREAD_STAT_MASK) != RT_THREAD_INIT) - { - /* we only support bind cpu before started phase. */ - return RT_ERROR; + cpu = (rt_uint8_t)(size_t)arg; + thread->bind_cpu = cpu > RT_CPUS_NR? RT_CPUS_NR : cpu; + break; } + #endif /*RT_USING_SMP*/ - cpu = (rt_uint8_t)(size_t)arg; - thread->bind_cpu = cpu > RT_CPUS_NR? RT_CPUS_NR : cpu; - break; - } -#endif /*RT_USING_SMP*/ - default: - break; + default: + break; } return RT_EOK; -- cgit v1.3.1