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:
chao an
2024-04-09 08:41:07 +08:00
committed by Xiang Xiao
parent 9967989b02
commit 09e5dca965
4 changed files with 9 additions and 24 deletions
-1
View File
@@ -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 */
};
+2 -2
View File
@@ -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;
}
}
+3 -5
View File
@@ -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
{
+4 -16
View File
@@ -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
{