commit
821c81e21a
|
@ -7,6 +7,7 @@
|
||||||
* Date Author Notes
|
* Date Author Notes
|
||||||
* 2018-01-26 Bernard Fix pthread_detach issue for a none-joinable
|
* 2018-01-26 Bernard Fix pthread_detach issue for a none-joinable
|
||||||
* thread.
|
* thread.
|
||||||
|
* 2019-02-07 Bernard Add _pthread_destroy to release pthread resource.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
@ -26,6 +27,32 @@ int pthread_system_init(void)
|
||||||
}
|
}
|
||||||
INIT_COMPONENT_EXPORT(pthread_system_init);
|
INIT_COMPONENT_EXPORT(pthread_system_init);
|
||||||
|
|
||||||
|
static void _pthread_destroy(_pthread_data_t *ptd)
|
||||||
|
{
|
||||||
|
/* delete joinable semaphore */
|
||||||
|
if (ptd->joinable_sem != RT_NULL)
|
||||||
|
rt_sem_delete(ptd->joinable_sem);
|
||||||
|
|
||||||
|
/* release thread resource */
|
||||||
|
if (ptd->attr.stack_base == RT_NULL)
|
||||||
|
{
|
||||||
|
/* release thread allocated stack */
|
||||||
|
rt_free(ptd->tid->stack_addr);
|
||||||
|
}
|
||||||
|
/* clean stack addr pointer */
|
||||||
|
ptd->tid->stack_addr = RT_NULL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* if this thread create the local thread data,
|
||||||
|
* delete it
|
||||||
|
*/
|
||||||
|
if (ptd->tls != RT_NULL) rt_free(ptd->tls);
|
||||||
|
rt_free(ptd->tid);
|
||||||
|
rt_free(ptd);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
static void _pthread_cleanup(rt_thread_t tid)
|
static void _pthread_cleanup(rt_thread_t tid)
|
||||||
{
|
{
|
||||||
_pthread_data_t *ptd;
|
_pthread_data_t *ptd;
|
||||||
|
@ -40,14 +67,14 @@ static void _pthread_cleanup(rt_thread_t tid)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* release pthread resource */
|
/* release pthread resource */
|
||||||
pthread_detach(tid);
|
_pthread_destroy(ptd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pthread_entry_stub(void *parameter)
|
static void pthread_entry_stub(void *parameter)
|
||||||
{
|
{
|
||||||
_pthread_data_t *ptd;
|
|
||||||
void *value;
|
void *value;
|
||||||
|
_pthread_data_t *ptd;
|
||||||
|
|
||||||
ptd = (_pthread_data_t *)parameter;
|
ptd = (_pthread_data_t *)parameter;
|
||||||
|
|
||||||
|
@ -181,60 +208,60 @@ RTM_EXPORT(pthread_create);
|
||||||
|
|
||||||
int pthread_detach(pthread_t thread)
|
int pthread_detach(pthread_t thread)
|
||||||
{
|
{
|
||||||
_pthread_data_t *ptd;
|
int ret = 0;
|
||||||
|
_pthread_data_t *ptd = _pthread_get_data(thread);
|
||||||
ptd = _pthread_get_data(thread);
|
|
||||||
|
|
||||||
|
rt_enter_critical();
|
||||||
if (ptd->attr.detachstate == PTHREAD_CREATE_DETACHED)
|
if (ptd->attr.detachstate == PTHREAD_CREATE_DETACHED)
|
||||||
{
|
{
|
||||||
/* The implementation has detected that the value specified by thread does not refer
|
/* The implementation has detected that the value specified by thread does not refer
|
||||||
* to a joinable thread.
|
* to a joinable thread.
|
||||||
*/
|
*/
|
||||||
return EINVAL;
|
ret = EINVAL;
|
||||||
|
goto __exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((thread->stat & RT_THREAD_STAT_MASK) == RT_THREAD_CLOSE)
|
if ((thread->stat & RT_THREAD_STAT_MASK) == RT_THREAD_CLOSE)
|
||||||
{
|
{
|
||||||
/* delete joinable semaphore */
|
/* this defunct pthread is not handled by idle */
|
||||||
if (ptd->joinable_sem != RT_NULL)
|
if (rt_sem_trytake(ptd->joinable_sem) != RT_EOK)
|
||||||
rt_sem_delete(ptd->joinable_sem);
|
{
|
||||||
/* detach thread object */
|
rt_sem_release(ptd->joinable_sem);
|
||||||
rt_thread_detach(ptd->tid);
|
|
||||||
|
|
||||||
/* release thread resource */
|
|
||||||
if (ptd->attr.stack_base == RT_NULL)
|
|
||||||
{
|
|
||||||
/* release thread allocated stack */
|
|
||||||
rt_free(ptd->tid->stack_addr);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* clean stack addr pointer */
|
|
||||||
ptd->tid->stack_addr = RT_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* if this thread create the local thread data,
|
|
||||||
* delete it
|
|
||||||
*/
|
|
||||||
if (ptd->tls != RT_NULL)
|
|
||||||
rt_free(ptd->tls);
|
|
||||||
rt_free(ptd->tid);
|
|
||||||
rt_free(ptd);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rt_enter_critical();
|
|
||||||
/* change to detach state */
|
/* change to detach state */
|
||||||
ptd->attr.detachstate = PTHREAD_CREATE_DETACHED;
|
ptd->attr.detachstate = PTHREAD_CREATE_DETACHED;
|
||||||
|
|
||||||
/* detach joinable semaphore */
|
/* detach joinable semaphore */
|
||||||
|
if (ptd->joinable_sem)
|
||||||
|
{
|
||||||
rt_sem_delete(ptd->joinable_sem);
|
rt_sem_delete(ptd->joinable_sem);
|
||||||
ptd->joinable_sem = RT_NULL;
|
ptd->joinable_sem = RT_NULL;
|
||||||
rt_exit_critical();
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* destroy this pthread */
|
||||||
|
_pthread_destroy(ptd);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
goto __exit;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* change to detach state */
|
||||||
|
ptd->attr.detachstate = PTHREAD_CREATE_DETACHED;
|
||||||
|
|
||||||
|
/* detach joinable semaphore */
|
||||||
|
if (ptd->joinable_sem)
|
||||||
|
{
|
||||||
|
rt_sem_delete(ptd->joinable_sem);
|
||||||
|
ptd->joinable_sem = RT_NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__exit:
|
||||||
|
rt_exit_critical();
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
RTM_EXPORT(pthread_detach);
|
RTM_EXPORT(pthread_detach);
|
||||||
|
|
||||||
|
@ -260,8 +287,8 @@ int pthread_join(pthread_t thread, void **value_ptr)
|
||||||
if (value_ptr != RT_NULL)
|
if (value_ptr != RT_NULL)
|
||||||
*value_ptr = ptd->return_value;
|
*value_ptr = ptd->return_value;
|
||||||
|
|
||||||
/* release resource */
|
/* destroy this pthread */
|
||||||
pthread_detach(thread);
|
_pthread_destroy(ptd);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -193,6 +193,8 @@ void rt_thread_idle_excute(void)
|
||||||
/* if it's a system object, not delete it */
|
/* if it's a system object, not delete it */
|
||||||
if (rt_object_is_systemobject((rt_object_t)thread) == RT_TRUE)
|
if (rt_object_is_systemobject((rt_object_t)thread) == RT_TRUE)
|
||||||
{
|
{
|
||||||
|
/* detach this object */
|
||||||
|
rt_object_detach((rt_object_t)thread);
|
||||||
/* unlock scheduler */
|
/* unlock scheduler */
|
||||||
rt_exit_critical();
|
rt_exit_critical();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue