[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:
parent
bf669dd02c
commit
2c9b7c10b9
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
93
src/thread.c
93
src/thread.c
|
@ -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,43 +478,13 @@ 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_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);
|
|
||||||
|
|
||||||
_thread_detach_from_mutex(thread);
|
_thread_detach_from_mutex(thread);
|
||||||
|
|
||||||
/* insert to defunct thread list */
|
/* insert to defunct thread list */
|
||||||
rt_thread_defunct_enqueue(thread);
|
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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue