summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordavidxu <davidxu@FreeBSD.org>2004-06-18 06:15:21 +0000
committerdavidxu <davidxu@FreeBSD.org>2004-06-18 06:15:21 +0000
commit673364f0efdd7d960926bfef902c7a229cc7db96 (patch)
tree1281642ab2abb3cb870c0d01ab34ccaafab19b00
parentf7aefb848dcdaeb3b6d733248100a4db4d28d314 (diff)
downloadFreeBSD-src-673364f0efdd7d960926bfef902c7a229cc7db96.zip
FreeBSD-src-673364f0efdd7d960926bfef902c7a229cc7db96.tar.gz
If thread singler wants to terminate other threads, make sure it includes
all threads except itself. Obtained from: julian
-rw-r--r--sys/kern/kern_thread.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c
index 8ec6f04..ea75cc5 100644
--- a/sys/kern/kern_thread.c
+++ b/sys/kern/kern_thread.c
@@ -849,6 +849,7 @@ thread_single(int force_exit)
struct thread *td;
struct thread *td2;
struct proc *p;
+ int remaining;
td = curthread;
p = td->td_proc;
@@ -870,7 +871,11 @@ thread_single(int force_exit)
p->p_flag |= P_STOPPED_SINGLE;
mtx_lock_spin(&sched_lock);
p->p_singlethread = td;
- while ((p->p_numthreads - p->p_suspcount) != 1) {
+ if (force_exit == SINGLE_EXIT)
+ remaining = p->p_numthreads;
+ else
+ remaining = p->p_numthreads - p->p_suspcount;
+ while (remaining != 1) {
FOREACH_THREAD_IN_PROC(p, td2) {
if (td2 == td)
continue;
@@ -898,10 +903,15 @@ thread_single(int force_exit)
}
}
}
+ if (force_exit == SINGLE_EXIT)
+ remaining = p->p_numthreads;
+ else
+ remaining = p->p_numthreads - p->p_suspcount;
+
/*
* Maybe we suspended some threads.. was it enough?
*/
- if ((p->p_numthreads - p->p_suspcount) == 1)
+ if (remaining == 1)
break;
/*
@@ -914,6 +924,10 @@ thread_single(int force_exit)
mtx_unlock_spin(&sched_lock);
PROC_LOCK(p);
mtx_lock_spin(&sched_lock);
+ if (force_exit == SINGLE_EXIT)
+ remaining = p->p_numthreads;
+ else
+ remaining = p->p_numthreads - p->p_suspcount;
}
if (force_exit == SINGLE_EXIT) {
if (td->td_upcall)
OpenPOWER on IntegriCloud