summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_thread.c
diff options
context:
space:
mode:
authordavidxu <davidxu@FreeBSD.org>2010-10-17 11:01:52 +0000
committerdavidxu <davidxu@FreeBSD.org>2010-10-17 11:01:52 +0000
commitc8ed8cb6af826805c05f3c01989c38878c5c158d (patch)
tree98bc1f465b25929349062dfad4a31b58f0a89e3c /sys/kern/kern_thread.c
parent0d755a144bd1f830a6e0842e888e0102f1974fe3 (diff)
downloadFreeBSD-src-c8ed8cb6af826805c05f3c01989c38878c5c158d.zip
FreeBSD-src-c8ed8cb6af826805c05f3c01989c38878c5c158d.tar.gz
- Insert thread0 into correct thread hash link list.
- In thr_exit() and kthread_exit(), only remove thread from hash if it can directly exit, otherwise let exit1() do it. - In thread_suspend_check(), fix cleanup code when thread needs to exit. This change seems fixed the "Bad link elm " panic found by Peter Holm. Stress testing: pho
Diffstat (limited to 'sys/kern/kern_thread.c')
-rw-r--r--sys/kern/kern_thread.c26
1 files changed, 7 insertions, 19 deletions
diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c
index 40652b6..5f07590 100644
--- a/sys/kern/kern_thread.c
+++ b/sys/kern/kern_thread.c
@@ -746,25 +746,23 @@ thread_suspend_check(int return_instead)
(p->p_flag & P_SINGLE_BOUNDARY) && return_instead)
return (ERESTART);
- /* If thread will exit, flush its pending signals */
- if ((p->p_flag & P_SINGLE_EXIT) && (p->p_singlethread != td))
- sigqueue_flush(&td->td_sigqueue);
-
- PROC_SLOCK(p);
- thread_stopped(p);
/*
* If the process is waiting for us to exit,
* this thread should just suicide.
* Assumes that P_SINGLE_EXIT implies P_STOPPED_SINGLE.
*/
if ((p->p_flag & P_SINGLE_EXIT) && (p->p_singlethread != td)) {
- PROC_SUNLOCK(p);
PROC_UNLOCK(p);
tidhash_remove(td);
PROC_LOCK(p);
+ tdsigcleanup(td);
PROC_SLOCK(p);
+ thread_stopped(p);
thread_exit();
}
+
+ PROC_SLOCK(p);
+ thread_stopped(p);
if (P_SHOULDSTOP(p) == P_STOPPED_SINGLE) {
if (p->p_numthreads == p->p_suspcount + 1) {
thread_lock(p->p_singlethread);
@@ -981,12 +979,7 @@ void
tidhash_add(struct thread *td)
{
rw_wlock(&tidhash_lock);
- thread_lock(td);
- if ((td->td_flags & TDF_TIDHASH) == 0) {
- LIST_INSERT_HEAD(TIDHASH(td->td_tid), td, td_hash);
- td->td_flags |= TDF_TIDHASH;
- }
- thread_unlock(td);
+ LIST_INSERT_HEAD(TIDHASH(td->td_tid), td, td_hash);
rw_wunlock(&tidhash_lock);
}
@@ -994,11 +987,6 @@ void
tidhash_remove(struct thread *td)
{
rw_wlock(&tidhash_lock);
- thread_lock(td);
- if ((td->td_flags & TDF_TIDHASH) != 0) {
- LIST_REMOVE(td, td_hash);
- td->td_flags &= ~TDF_TIDHASH;
- }
- thread_unlock(td);
+ LIST_REMOVE(td, td_hash);
rw_wunlock(&tidhash_lock);
}
OpenPOWER on IntegriCloud