[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 <smokewood@qq.com>
This commit is contained in:
Shell 2024-05-01 12:49:09 +08:00 committed by GitHub
parent bf669dd02c
commit 2c9b7c10b9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 55 additions and 59 deletions

View File

@ -202,19 +202,11 @@ void dlmodule_destroy_subthread(struct rt_dlmodule *module, rt_thread_t thread)
/* lock scheduler to prevent scheduling in cleanup function. */ /* lock scheduler to prevent scheduling in cleanup function. */
rt_enter_critical(); 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)); 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 */ /* invoke thread cleanup */
if (thread->cleanup != RT_NULL) if (thread->cleanup != RT_NULL)
thread->cleanup(thread); thread->cleanup(thread);

View File

@ -160,6 +160,7 @@ rt_thread_t rt_thread_create(const char *name,
rt_uint8_t priority, rt_uint8_t priority,
rt_uint32_t tick); rt_uint32_t tick);
rt_err_t rt_thread_delete(rt_thread_t thread); rt_err_t rt_thread_delete(rt_thread_t thread);
rt_err_t rt_thread_close(rt_thread_t thread);
#endif /* RT_USING_HEAP */ #endif /* RT_USING_HEAP */
rt_thread_t rt_thread_self(void); rt_thread_t rt_thread_self(void);
rt_thread_t rt_thread_find(char *name); rt_thread_t rt_thread_find(char *name);

View File

@ -79,25 +79,14 @@ RT_OBJECT_HOOKLIST_DEFINE(rt_thread_inited);
static void _thread_exit(void) static void _thread_exit(void)
{ {
struct rt_thread *thread; struct rt_thread *thread;
rt_sched_lock_level_t slvl;
rt_base_t critical_level; rt_base_t critical_level;
/* get current thread */ /* get current thread */
thread = rt_thread_self(); thread = rt_thread_self();
critical_level = rt_enter_critical(); critical_level = rt_enter_critical();
rt_sched_lock(&slvl);
/* remove from schedule */ rt_thread_close(thread);
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);
/* insert to defunct thread list */ /* insert to defunct thread list */
rt_thread_defunct_enqueue(thread); rt_thread_defunct_enqueue(thread);
@ -410,6 +399,52 @@ rt_err_t rt_thread_startup(rt_thread_t thread)
} }
RTM_EXPORT(rt_thread_startup); 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); 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) static rt_err_t _thread_detach(rt_thread_t thread)
{ {
rt_err_t error; rt_err_t error;
rt_sched_lock_level_t slvl;
rt_uint8_t thread_status;
rt_base_t critical_level; rt_base_t critical_level;
/** /**
@ -445,42 +478,12 @@ static rt_err_t _thread_detach(rt_thread_t thread)
*/ */
critical_level = rt_enter_critical(); critical_level = rt_enter_critical();
/* before checking status of scheduler */ error = rt_thread_close(thread);
rt_sched_lock(&slvl);
/* check if thread is already closed */ _thread_detach_from_mutex(thread);
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 */ /* insert to defunct thread list */
rt_timer_detach(&(thread->thread_timer)); rt_thread_defunct_enqueue(thread);
/* 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;
}
rt_exit_critical_safe(critical_level); rt_exit_critical_safe(critical_level);
return error; return error;