diff options
author | jeff <jeff@FreeBSD.org> | 2003-04-01 01:26:20 +0000 |
---|---|---|
committer | jeff <jeff@FreeBSD.org> | 2003-04-01 01:26:20 +0000 |
commit | 1b4d7b91cef2a324650912a6c4a57c1247f72de9 (patch) | |
tree | fe9429d1c952f94fe7724a5e8d93774c365108da /sys | |
parent | ddd831445867d7b38b022286ecc4d99f0bcbca48 (diff) | |
download | FreeBSD-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.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/kern_exec.c | 2 | ||||
-rw-r--r-- | sys/kern/kern_exit.c | 6 | ||||
-rw-r--r-- | sys/kern/kern_fork.c | 5 | ||||
-rw-r--r-- | sys/kern/kern_kse.c | 10 | ||||
-rw-r--r-- | sys/kern/kern_synch.c | 2 | ||||
-rw-r--r-- | sys/kern/kern_thread.c | 10 |
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) { |