From 2c9b7c10b9ff6b4509945376bb4e25dd18c1ce25 Mon Sep 17 00:00:00 2001 From: Shell Date: Wed, 1 May 2024 12:49:09 +0800 Subject: [PATCH] [kernel] add rt_thread_close() * [thread] Add rt_thread_close() This patch introduces a new function `rt_thread_close()` to enhances the usability and maintainability by providing a dedicated mechanism for closing threads. - A new function `rt_thread_close()` is added to the API, providing a standardized approach for closing threads. - The `rt_thread_close()` function removes a thread from the thread queue, updates its status to indicate closure, and performs the thread timer detaching which is a embedded timer in thread object. - Additionally, the `rt_thread_detach()` function is modified to utilize `rt_thread_close()` internally, streamlining the thread detachment process. Signed-off-by: Shell --- components/libc/posix/libdl/dlmodule.c | 14 +--- include/rtthread.h | 1 + src/thread.c | 99 +++++++++++++------------- 3 files changed, 55 insertions(+), 59 deletions(-) diff --git a/components/libc/posix/libdl/dlmodule.c b/components/libc/posix/libdl/dlmodule.c index 1f245e4121..2679296731 100644 --- a/components/libc/posix/libdl/dlmodule.c +++ b/components/libc/posix/libdl/dlmodule.c @@ -202,19 +202,11 @@ void dlmodule_destroy_subthread(struct rt_dlmodule *module, rt_thread_t thread) /* lock scheduler to prevent scheduling in cleanup function. */ rt_enter_critical(); - /* remove thread from thread_list (ready or defunct thread list) */ + rt_thread_close(thread); + + /* remove thread from thread_list (defunct thread list) */ rt_list_remove(&RT_THREAD_LIST_NODE(thread)); - if ((thread->stat & RT_THREAD_STAT_MASK) != RT_THREAD_CLOSE && - (thread->thread_timer.parent.type == (RT_Object_Class_Static | RT_Object_Class_Timer))) - { - /* release thread timer */ - rt_timer_detach(&(thread->thread_timer)); - } - - /* change stat */ - thread->stat = RT_THREAD_CLOSE; - /* invoke thread cleanup */ if (thread->cleanup != RT_NULL) thread->cleanup(thread); diff --git a/include/rtthread.h b/include/rtthread.h index 5e70c5dd63..a511a1f5c5 100644 --- a/include/rtthread.h +++ b/include/rtthread.h @@ -160,6 +160,7 @@ rt_thread_t rt_thread_create(const char *name, rt_uint8_t priority, rt_uint32_t tick); rt_err_t rt_thread_delete(rt_thread_t thread); +rt_err_t rt_thread_close(rt_thread_t thread); #endif /* RT_USING_HEAP */ rt_thread_t rt_thread_self(void); rt_thread_t rt_thread_find(char *name); diff --git a/src/thread.c b/src/thread.c index 1b489cf76f..170d61eec8 100644 --- a/src/thread.c +++ b/src/thread.c @@ -79,25 +79,14 @@ RT_OBJECT_HOOKLIST_DEFINE(rt_thread_inited); static void _thread_exit(void) { struct rt_thread *thread; - rt_sched_lock_level_t slvl; rt_base_t critical_level; /* get current thread */ thread = rt_thread_self(); critical_level = rt_enter_critical(); - rt_sched_lock(&slvl); - /* remove from schedule */ - rt_sched_remove_thread(thread); - - /* remove it from timer list */ - rt_timer_detach(&thread->thread_timer); - - /* change stat */ - rt_sched_thread_close(thread); - - rt_sched_unlock(slvl); + rt_thread_close(thread); /* insert to defunct thread list */ rt_thread_defunct_enqueue(thread); @@ -410,6 +399,52 @@ rt_err_t rt_thread_startup(rt_thread_t thread) } RTM_EXPORT(rt_thread_startup); +/** + * @brief This function will close a thread. The thread object will be removed from + * thread queue and detached/deleted from the system object management. + * It's different from rt_thread_delete or rt_thread_detach that this will not enqueue + * the closing thread to cleanup queue. + * + * @param thread is the thread to be closed. + * + * @return Return the operation status. If the return value is RT_EOK, the function is successfully executed. + * If the return value is any other values, it means this operation failed. + */ +rt_err_t rt_thread_close(rt_thread_t thread) +{ + rt_sched_lock_level_t slvl; + rt_uint8_t thread_status; + + /* forbid scheduling on current core if closing current thread */ + RT_ASSERT(thread != rt_thread_self() || rt_critical_level()); + + /* before checking status of scheduler */ + rt_sched_lock(&slvl); + + /* check if thread is already closed */ + thread_status = rt_sched_thread_get_stat(thread); + if (thread_status != RT_THREAD_CLOSE) + { + if (thread_status != RT_THREAD_INIT) + { + /* remove from schedule */ + rt_sched_remove_thread(thread); + } + + /* release thread timer */ + rt_timer_detach(&(thread->thread_timer)); + + /* change stat */ + rt_sched_thread_close(thread); + } + + /* scheduler works are done */ + rt_sched_unlock(slvl); + + return RT_EOK; +} +RTM_EXPORT(rt_thread_close); + static rt_err_t _thread_detach(rt_thread_t thread); /** @@ -435,8 +470,6 @@ RTM_EXPORT(rt_thread_detach); static rt_err_t _thread_detach(rt_thread_t thread) { rt_err_t error; - rt_sched_lock_level_t slvl; - rt_uint8_t thread_status; rt_base_t critical_level; /** @@ -445,42 +478,12 @@ static rt_err_t _thread_detach(rt_thread_t thread) */ critical_level = rt_enter_critical(); - /* before checking status of scheduler */ - rt_sched_lock(&slvl); + error = rt_thread_close(thread); - /* check if thread is already closed */ - thread_status = rt_sched_thread_get_stat(thread); - if (thread_status != RT_THREAD_CLOSE) - { - if (thread_status != RT_THREAD_INIT) - { - /* remove from schedule */ - rt_sched_remove_thread(thread); - } + _thread_detach_from_mutex(thread); - /* release thread timer */ - rt_timer_detach(&(thread->thread_timer)); - - /* change stat */ - rt_sched_thread_close(thread); - - /* scheduler works are done */ - rt_sched_unlock(slvl); - - _thread_detach_from_mutex(thread); - - /* insert to defunct thread list */ - rt_thread_defunct_enqueue(thread); - - error = RT_EOK; - } - else - { - rt_sched_unlock(slvl); - - /* already closed */ - error = RT_EOK; - } + /* insert to defunct thread list */ + rt_thread_defunct_enqueue(thread); rt_exit_critical_safe(critical_level); return error;