summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordavidxu <davidxu@FreeBSD.org>2010-10-23 13:16:39 +0000
committerdavidxu <davidxu@FreeBSD.org>2010-10-23 13:16:39 +0000
commit841633e7b6a19e5a095062370dd1a64cbe0d84ff (patch)
tree4147331061e1ffc446d09074add0b9e0239f0cd7
parent26a4fa1adc1004ceee6d2d1bf13287d27ea3cd42 (diff)
downloadFreeBSD-src-841633e7b6a19e5a095062370dd1a64cbe0d84ff.zip
FreeBSD-src-841633e7b6a19e5a095062370dd1a64cbe0d84ff.tar.gz
In thr_exit() and kthread_exit(), only remove thread from
hash if it can directly exit, otherwise let exit1() do it. The change should be in r213950, but for unknown reason, it was lost.
-rw-r--r--sys/kern/kern_kthread.c6
-rw-r--r--sys/kern/kern_thr.c13
2 files changed, 12 insertions, 7 deletions
diff --git a/sys/kern/kern_kthread.c b/sys/kern/kern_kthread.c
index 9ab0922..be40c80 100644
--- a/sys/kern/kern_kthread.c
+++ b/sys/kern/kern_kthread.c
@@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
#include <sys/mutex.h>
#include <sys/proc.h>
#include <sys/resourcevar.h>
+#include <sys/rwlock.h>
#include <sys/signalvar.h>
#include <sys/sx.h>
#include <sys/unistd.h>
@@ -315,17 +316,20 @@ kthread_exit(void)
p = curthread->td_proc;
- tidhash_remove(curthread);
/* A module may be waiting for us to exit. */
wakeup(curthread);
+ rw_wlock(&tidhash_lock);
PROC_LOCK(p);
if (p->p_numthreads == 1) {
PROC_UNLOCK(p);
+ rw_wunlock(&tidhash_lock);
kproc_exit(0);
/* NOTREACHED. */
}
+ LIST_REMOVE(curthread, td_hash);
+ rw_wunlock(&tidhash_lock);
PROC_SLOCK(p);
thread_exit();
}
diff --git a/sys/kern/kern_thr.c b/sys/kern/kern_thr.c
index 3a9c721..75656f0 100644
--- a/sys/kern/kern_thr.c
+++ b/sys/kern/kern_thr.c
@@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
#include <sys/proc.h>
#include <sys/posix4.h>
#include <sys/resourcevar.h>
+#include <sys/rwlock.h>
#include <sys/sched.h>
#include <sys/sysctl.h>
#include <sys/smp.h>
@@ -284,23 +285,23 @@ thr_exit(struct thread *td, struct thr_exit_args *uap)
kern_umtx_wake(td, uap->state, INT_MAX, 0);
}
- tidhash_remove(td);
-
+ rw_wlock(&tidhash_lock);
PROC_LOCK(p);
- tdsigcleanup(td);
- PROC_SLOCK(p);
-
/*
* Shutting down last thread in the proc. This will actually
* call exit() in the trampoline when it returns.
*/
if (p->p_numthreads != 1) {
+ LIST_REMOVE(td, td_hash);
+ rw_wunlock(&tidhash_lock);
+ tdsigcleanup(td);
+ PROC_SLOCK(p);
thread_stopped(p);
thread_exit();
/* NOTREACHED */
}
- PROC_SUNLOCK(p);
PROC_UNLOCK(p);
+ rw_wunlock(&tidhash_lock);
return (0);
}
OpenPOWER on IntegriCloud