summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjeff <jeff@FreeBSD.org>2003-04-01 01:26:20 +0000
committerjeff <jeff@FreeBSD.org>2003-04-01 01:26:20 +0000
commit1b4d7b91cef2a324650912a6c4a57c1247f72de9 (patch)
treefe9429d1c952f94fe7724a5e8d93774c365108da
parentddd831445867d7b38b022286ecc4d99f0bcbca48 (diff)
downloadFreeBSD-src-1b4d7b91cef2a324650912a6c4a57c1247f72de9.zip
FreeBSD-src-1b4d7b91cef2a324650912a6c4a57c1247f72de9.tar.gz
- Borrow the KSE single threading code for exec and exit. We use the check
if (p->p_numthreads > 1) and not a flag because action is only necessary if there are other threads. The rest of the system has no need to identify thr threaded processes. - In kern_thread.c use thr_exit1() instead of thread_exit() if P_THREADED is not set.
-rw-r--r--sys/kern/kern_exec.c2
-rw-r--r--sys/kern/kern_exit.c6
-rw-r--r--sys/kern/kern_fork.c5
-rw-r--r--sys/kern/kern_kse.c10
-rw-r--r--sys/kern/kern_synch.c2
-rw-r--r--sys/kern/kern_thread.c10
6 files changed, 25 insertions, 10 deletions
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
index a8c668b..7f5c819 100644
--- a/sys/kern/kern_exec.c
+++ b/sys/kern/kern_exec.c
@@ -189,7 +189,7 @@ kern_execve(td, fname, argv, envv, mac_p)
PROC_LOCK(p);
KASSERT((p->p_flag & P_INEXEC) == 0,
("%s(): process already has P_INEXEC flag", __func__));
- if (p->p_flag & P_THREADED) {
+ if (p->p_flag & P_THREADED || p->p_numthreads > 1) {
if (thread_single(SINGLE_EXIT)) {
PROC_UNLOCK(p);
return (ERESTART); /* Try again later. */
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index dd537b2..fee6caf 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -129,15 +129,17 @@ exit1(struct thread *td, int rv)
}
/*
- * XXXKSE: MUST abort all other threads before proceeding past here.
+ * MUST abort all other threads before proceeding past here.
*/
PROC_LOCK(p);
- if (p->p_flag & P_THREADED) {
+ if (p->p_flag & P_THREADED || p->p_numthreads > 1) {
/*
* First check if some other thread got here before us..
* if so, act apropriatly, (exit or suspend);
*/
+ DROP_GIANT();
thread_suspend_check(0);
+ PICKUP_GIANT();
/*
* Kill off the other threads. This requires
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index 11a94d9..9a74d25 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -265,6 +265,11 @@ fork1(td, flags, pages, procp)
return (0);
}
+ /*
+ * Note 1:1 allows for forking with one thread coming out on the
+ * other side with the expectation that the process is about to
+ * exec.
+ */
if (p1->p_flag & P_THREADED) {
/*
* Idle the other threads for a second.
diff --git a/sys/kern/kern_kse.c b/sys/kern/kern_kse.c
index b9c85f8..3699461 100644
--- a/sys/kern/kern_kse.c
+++ b/sys/kern/kern_kse.c
@@ -1813,7 +1813,7 @@ thread_single(int force_exit)
PROC_LOCK_ASSERT(p, MA_OWNED);
KASSERT((td != NULL), ("curthread is NULL"));
- if ((p->p_flag & P_THREADED) == 0)
+ if ((p->p_flag & P_THREADED) == 0 && p->p_numthreads == 1)
return (0);
/* Is someone already single threading? */
@@ -1872,6 +1872,7 @@ thread_single(int force_exit)
* In the mean time we suspend as well.
*/
thread_suspend_one(td);
+ /* XXX If you recursed this is broken. */
mtx_unlock(&Giant);
PROC_UNLOCK(p);
p->p_stats->p_ru.ru_nvcsw++;
@@ -1961,15 +1962,18 @@ thread_suspend_check(int return_instead)
if ((p->p_flag & P_SINGLE_EXIT) && (p->p_singlethread != td)) {
while (mtx_owned(&Giant))
mtx_unlock(&Giant);
- thread_exit();
+ if (p->p_flag & P_THREADED)
+ thread_exit();
+ else
+ thr_exit1();
}
+ mtx_assert(&Giant, MA_NOTOWNED);
/*
* When a thread suspends, it just
* moves to the processes's suspend queue
* and stays there.
*/
- mtx_assert(&Giant, MA_NOTOWNED);
thread_suspend_one(td);
PROC_UNLOCK(p);
if (P_SHOULDSTOP(p) == P_STOPPED_SINGLE) {
diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c
index 0c479c7..cf6591f 100644
--- a/sys/kern/kern_synch.c
+++ b/sys/kern/kern_synch.c
@@ -161,7 +161,7 @@ msleep(ident, mtx, priority, wmesg, timo)
* the thread (recursion here might be bad).
* Hence the TDF_INMSLEEP flag.
*/
- if (p->p_flag & P_THREADED) {
+ if (p->p_flag & P_THREADED || p->p_numthreads > 1) {
/*
* Just don't bother if we are exiting
* and not the exiting thread or thread was marked as
diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c
index b9c85f8..3699461 100644
--- a/sys/kern/kern_thread.c
+++ b/sys/kern/kern_thread.c
@@ -1813,7 +1813,7 @@ thread_single(int force_exit)
PROC_LOCK_ASSERT(p, MA_OWNED);
KASSERT((td != NULL), ("curthread is NULL"));
- if ((p->p_flag & P_THREADED) == 0)
+ if ((p->p_flag & P_THREADED) == 0 && p->p_numthreads == 1)
return (0);
/* Is someone already single threading? */
@@ -1872,6 +1872,7 @@ thread_single(int force_exit)
* In the mean time we suspend as well.
*/
thread_suspend_one(td);
+ /* XXX If you recursed this is broken. */
mtx_unlock(&Giant);
PROC_UNLOCK(p);
p->p_stats->p_ru.ru_nvcsw++;
@@ -1961,15 +1962,18 @@ thread_suspend_check(int return_instead)
if ((p->p_flag & P_SINGLE_EXIT) && (p->p_singlethread != td)) {
while (mtx_owned(&Giant))
mtx_unlock(&Giant);
- thread_exit();
+ if (p->p_flag & P_THREADED)
+ thread_exit();
+ else
+ thr_exit1();
}
+ mtx_assert(&Giant, MA_NOTOWNED);
/*
* When a thread suspends, it just
* moves to the processes's suspend queue
* and stays there.
*/
- mtx_assert(&Giant, MA_NOTOWNED);
thread_suspend_one(td);
PROC_UNLOCK(p);
if (P_SHOULDSTOP(p) == P_STOPPED_SINGLE) {
OpenPOWER on IntegriCloud