diff options
author | kib <kib@FreeBSD.org> | 2014-09-10 09:47:16 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2014-09-10 09:47:16 +0000 |
commit | f5031098f409fce5a8992e18204a601ba0ff67ef (patch) | |
tree | 13b8a7a9a5b0dd94e80cd96e4ac15e200c42480c | |
parent | b6b97251b9843859e56227a7ad729df0191595f0 (diff) | |
download | FreeBSD-src-f5031098f409fce5a8992e18204a601ba0ff67ef.zip FreeBSD-src-f5031098f409fce5a8992e18204a601ba0ff67ef.tar.gz |
MFC r271000:
Delay the return from thread_single(SINGLE_EXIT) until all threads are
really destroyed by thread_stash() after the last switch out.
MFC r271007:
Retire thread_unthread().
MFC r271008:
Style.
Approved by: re (marius)
-rw-r--r-- | sys/kern/kern_thread.c | 42 | ||||
-rw-r--r-- | sys/sys/proc.h | 1 |
2 files changed, 19 insertions, 24 deletions
diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c index d777b63..122a13d 100644 --- a/sys/kern/kern_thread.c +++ b/sys/kern/kern_thread.c @@ -433,6 +433,7 @@ thread_exit(void) */ if (p->p_flag & P_HADTHREADS) { if (p->p_numthreads > 1) { + atomic_add_int(&td->td_proc->p_exitthreads, 1); thread_unlink(td); td2 = FIRST_THREAD_IN_PROC(p); sched_exit_thread(td2, td); @@ -453,7 +454,6 @@ thread_exit(void) } } - atomic_add_int(&td->td_proc->p_exitthreads, 1); PCPU_SET(deadthread, td); } else { /* @@ -508,14 +508,12 @@ thread_wait(struct proc *p) struct thread *td; mtx_assert(&Giant, MA_NOTOWNED); - KASSERT((p->p_numthreads == 1), ("Multiple threads in wait1()")); + KASSERT(p->p_numthreads == 1, ("multiple threads in thread_wait()")); + KASSERT(p->p_exitthreads == 0, ("p_exitthreads leaking")); td = FIRST_THREAD_IN_PROC(p); /* Lock the last thread so we spin until it exits cpu_throw(). */ thread_lock(td); thread_unlock(td); - /* Wait for any remaining threads to exit cpu_throw(). */ - while (p->p_exitthreads) - sched_relinquish(curthread); lock_profile_thread_exit(td); cpuset_rel(td->td_cpuset); td->td_cpuset = NULL; @@ -552,18 +550,6 @@ thread_link(struct thread *td, struct proc *p) } /* - * Convert a process with one thread to an unthreaded process. - */ -void -thread_unthread(struct thread *td) -{ - struct proc *p = td->td_proc; - - KASSERT((p->p_numthreads == 1), ("Unthreading with >1 threads")); - p->p_flag &= ~P_HADTHREADS; -} - -/* * Called from: * thread_exit() */ @@ -715,14 +701,24 @@ stopme: } if (mode == SINGLE_EXIT) { /* - * We have gotten rid of all the other threads and we - * are about to either exit or exec. In either case, - * we try our utmost to revert to being a non-threaded - * process. + * Convert the process to an unthreaded process. The + * SINGLE_EXIT is called by exit1() or execve(), in + * both cases other threads must be retired. */ + KASSERT(p->p_numthreads == 1, ("Unthreading with >1 threads")); p->p_singlethread = NULL; - p->p_flag &= ~(P_STOPPED_SINGLE | P_SINGLE_EXIT); - thread_unthread(td); + p->p_flag &= ~(P_STOPPED_SINGLE | P_SINGLE_EXIT | P_HADTHREADS); + + /* + * Wait for any remaining threads to exit cpu_throw(). + */ + while (p->p_exitthreads != 0) { + PROC_SUNLOCK(p); + PROC_UNLOCK(p); + sched_relinquish(td); + PROC_LOCK(p); + PROC_SLOCK(p); + } } PROC_SUNLOCK(p); return (0); diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 3d2e9e5..6865fe9 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -952,7 +952,6 @@ void thread_suspend_one(struct thread *td); void thread_unlink(struct thread *td); void thread_unsuspend(struct proc *p); int thread_unsuspend_one(struct thread *td); -void thread_unthread(struct thread *td); void thread_wait(struct proc *p); struct thread *thread_find(struct proc *p, lwpid_t tid); |