From 09e5dca9657938d7f7c0da9793cbbc94946f820d Mon Sep 17 00:00:00 2001 From: chao an Date: Tue, 9 Apr 2024 08:41:07 +0800 Subject: [PATCH] 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 --- include/nuttx/sched.h | 1 - sched/pthread/pthread_completejoin.c | 4 ++-- sched/pthread/pthread_detach.c | 8 +++----- sched/pthread/pthread_join.c | 20 ++++---------------- 4 files changed, 9 insertions(+), 24 deletions(-) diff --git a/include/nuttx/sched.h b/include/nuttx/sched.h index a0eaaec2a10..d3504c0dda7 100644 --- a/include/nuttx/sched.h +++ b/include/nuttx/sched.h @@ -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 */ }; diff --git a/sched/pthread/pthread_completejoin.c b/sched/pthread/pthread_completejoin.c index bcc3637c850..e7c60e0d8a5 100644 --- a/sched/pthread/pthread_completejoin.c +++ b/sched/pthread/pthread_completejoin.c @@ -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; } } diff --git a/sched/pthread/pthread_detach.c b/sched/pthread/pthread_detach.c index 48c6d09f2d2..9eac0625ded 100644 --- a/sched/pthread/pthread_detach.c +++ b/sched/pthread/pthread_detach.c @@ -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 { diff --git a/sched/pthread/pthread_join.c b/sched/pthread/pthread_join.c index 27422008bf3..6094fc4735f 100644 --- a/sched/pthread/pthread_join.c +++ b/sched/pthread/pthread_join.c @@ -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 {