diff options
author | davidxu <davidxu@FreeBSD.org> | 2003-03-11 00:07:53 +0000 |
---|---|---|
committer | davidxu <davidxu@FreeBSD.org> | 2003-03-11 00:07:53 +0000 |
commit | bb4f70ad77336204f47c1f34d447e9b21b4a0510 (patch) | |
tree | ff2e7470175d49774ac87c9aa830640b3bc32c2d /sys/kern/kern_thread.c | |
parent | 29e1315705c89238422661038791bcd98cf379f0 (diff) | |
download | FreeBSD-src-bb4f70ad77336204f47c1f34d447e9b21b4a0510.zip FreeBSD-src-bb4f70ad77336204f47c1f34d447e9b21b4a0510.tar.gz |
Fix threaded process job control bug. SMP tested.
Reviewed by: julian
Diffstat (limited to 'sys/kern/kern_thread.c')
-rw-r--r-- | sys/kern/kern_thread.c | 44 |
1 files changed, 16 insertions, 28 deletions
diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c index 18b55d5..2c8e65f 100644 --- a/sys/kern/kern_thread.c +++ b/sys/kern/kern_thread.c @@ -452,6 +452,7 @@ kse_exit(struct thread *td, struct kse_exit_args *uap) kse_purge_group(td); ke->ke_flags |= KEF_EXIT; } + thread_stopped(p); thread_exit(); /* NOTREACHED */ } @@ -1512,6 +1513,7 @@ thread_user_enter(struct proc *p, struct thread *td) if ((p->p_flag & P_SINGLE_EXIT) && (p->p_singlethread != td)) { PROC_LOCK(p); mtx_lock_spin(&sched_lock); + thread_stopped(p); thread_exit(); /* NOTREACHED */ } @@ -1627,21 +1629,17 @@ thread_userret(struct thread *td, struct trapframe *frame) mtx_unlock_spin(&sched_lock); } else if (td->td_mailbox) { error = thread_export_context(td); - if (error) { - PROC_LOCK(td->td_proc); - mtx_lock_spin(&sched_lock); - /* possibly upcall with error? */ - } else { - PROC_LOCK(td->td_proc); - mtx_lock_spin(&sched_lock); - /* - * There are upcall threads waiting for - * work to do, wake one of them up. - * XXXKSE Maybe wake all of them up. - */ - if (kg->kg_upsleeps) - wakeup_one(&kg->kg_completed); - } + /* possibly upcall with error? */ + PROC_LOCK(p); + /* + * There are upcall threads waiting for + * work to do, wake one of them up. + * XXXKSE Maybe wake all of them up. + */ + if (!error && kg->kg_upsleeps) + wakeup_one(&kg->kg_completed); + mtx_lock_spin(&sched_lock); + thread_stopped(p); thread_exit(); /* NOTREACHED */ } @@ -1918,13 +1916,14 @@ thread_suspend_check(int return_instead) if (return_instead) return (1); + mtx_lock_spin(&sched_lock); + thread_stopped(p); /* * If the process is waiting for us to exit, * this thread should just suicide. * Assumes that P_SINGLE_EXIT implies P_STOPPED_SINGLE. */ if ((p->p_flag & P_SINGLE_EXIT) && (p->p_singlethread != td)) { - mtx_lock_spin(&sched_lock); while (mtx_owned(&Giant)) mtx_unlock(&Giant); thread_exit(); @@ -1935,18 +1934,6 @@ thread_suspend_check(int return_instead) * moves to the processes's suspend queue * and stays there. */ - mtx_lock_spin(&sched_lock); - if ((p->p_flag & P_STOPPED_SIG) && - (p->p_suspcount+1 == p->p_numthreads)) { - mtx_unlock_spin(&sched_lock); - PROC_LOCK(p->p_pptr); - if ((p->p_pptr->p_procsig->ps_flag & - PS_NOCLDSTOP) == 0) { - psignal(p->p_pptr, SIGCHLD); - } - PROC_UNLOCK(p->p_pptr); - mtx_lock_spin(&sched_lock); - } mtx_assert(&Giant, MA_NOTOWNED); thread_suspend_one(td); PROC_UNLOCK(p); @@ -1969,6 +1956,7 @@ thread_suspend_one(struct thread *td) struct proc *p = td->td_proc; mtx_assert(&sched_lock, MA_OWNED); + KASSERT(!TD_IS_SUSPENDED(td), ("already suspended")); p->p_suspcount++; TD_SET_SUSPENDED(td); TAILQ_INSERT_TAIL(&p->p_suspended, td, td_runq); |