summaryrefslogtreecommitdiffstats
path: root/sys
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 /sys
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.
Diffstat (limited to 'sys')
-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