mirror of
https://github.com/apache/nuttx.git
synced 2026-05-18 00:34:10 +08:00
sched/pthread: detached thread should destroy the join info
In order to ensure the detached thread obtain the correct return value from pthread_join()/pthread_cancel(), the detached thread will create joininfo to save the detached status after thread destroyed. If there are too many of detached threads in the process group, the joininfo will consume too much memory. This is not friendly to embedded MCU devices. This commit keep the semantics as #11898 was introduced, will no longer save joininfo for detached threads to avoid wasting memory. Signed-off-by: chao an <anchao@lixiang.com>
This commit is contained in:
@@ -397,7 +397,6 @@ struct task_join_s
|
||||
{
|
||||
sq_entry_t entry; /* Implements link list */
|
||||
pid_t pid; /* Includes pid */
|
||||
bool detached; /* true: pthread_detached'ed */
|
||||
pthread_addr_t exit_value; /* Returned data */
|
||||
};
|
||||
|
||||
|
||||
@@ -95,12 +95,12 @@ int pthread_completejoin(pid_t pid, FAR void *exit_value)
|
||||
nxsem_post(&wtcb->join_sem);
|
||||
}
|
||||
}
|
||||
else if (!sq_is_singular(&tcb->group->tg_members))
|
||||
else if (!sq_is_singular(&tcb->group->tg_members) &&
|
||||
(tcb->flags & TCB_FLAG_DETACHED) == 0)
|
||||
{
|
||||
ret = pthread_findjoininfo(tcb->group, pid, &join, true);
|
||||
if (ret == OK)
|
||||
{
|
||||
join->detached = !!(tcb->flags & TCB_FLAG_DETACHED);
|
||||
join->exit_value = exit_value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,16 +71,14 @@ int pthread_detach(pthread_t thread)
|
||||
nxrmutex_lock(&group->tg_joinlock);
|
||||
|
||||
tcb = nxsched_get_tcb((pid_t)thread);
|
||||
if (tcb == NULL)
|
||||
if (tcb == NULL || (tcb->flags & TCB_FLAG_JOIN_COMPLETED) != 0)
|
||||
{
|
||||
/* If tcb has been destroyed, update the pending join
|
||||
* status in the group.
|
||||
*/
|
||||
/* Destroy the join information */
|
||||
|
||||
ret = pthread_findjoininfo(group, (pid_t)thread, &join, false);
|
||||
if (ret == OK)
|
||||
{
|
||||
join->detached = true;
|
||||
pthread_destroyjoin(group, join);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -89,26 +89,14 @@ int pthread_join(pthread_t thread, FAR pthread_addr_t *pexit_value)
|
||||
ret = pthread_findjoininfo(group, (pid_t)thread, &join, false);
|
||||
if (ret == OK)
|
||||
{
|
||||
/* If the task is terminated, maintain the same behavior as Linux:
|
||||
* 1. Join detached task will always return EINVAL.
|
||||
* 2. Other threads will destroy the join information after
|
||||
* obtain the exit value, ESRCH will return if calling
|
||||
* pthread_join() again
|
||||
*/
|
||||
/* Destroy the join information after obtain the exit value */
|
||||
|
||||
if (join->detached)
|
||||
if (pexit_value != NULL)
|
||||
{
|
||||
ret = EINVAL;
|
||||
*pexit_value = join->exit_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pexit_value != NULL)
|
||||
{
|
||||
*pexit_value = join->exit_value;
|
||||
}
|
||||
|
||||
pthread_destroyjoin(group, join);
|
||||
}
|
||||
pthread_destroyjoin(group, join);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user