From 2062caca2494bf113adefa9ca01f9f5fb24ad7b9 Mon Sep 17 00:00:00 2001 From: davidxu Date: Thu, 23 Oct 2008 07:55:38 +0000 Subject: Actually, for signal and thread suspension, extra process spin lock is unnecessary, the normal process lock and thread lock are enough. The spin lock is still needed for process and thread exiting to mimic single sched_lock. --- sys/kern/subr_sleepqueue.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'sys/kern/subr_sleepqueue.c') diff --git a/sys/kern/subr_sleepqueue.c b/sys/kern/subr_sleepqueue.c index f9bac9b..751fa64 100644 --- a/sys/kern/subr_sleepqueue.c +++ b/sys/kern/subr_sleepqueue.c @@ -395,6 +395,8 @@ sleepq_catch_signals(void *wchan, int pri) sleepq_switch(wchan, pri); return (0); } + +catch_sig: thread_unlock(td); mtx_unlock_spin(&sc->sc_lock); CTR3(KTR_PROC, "sleepq catching signals: thread %p (pid %ld, %s)", @@ -414,20 +416,19 @@ sleepq_catch_signals(void *wchan, int pri) ret = ERESTART; mtx_unlock(&ps->ps_mtx); } - /* - * Lock the per-process spinlock prior to dropping the PROC_LOCK - * to avoid a signal delivery race. PROC_LOCK, PROC_SLOCK, and - * thread_lock() are currently held in tdsignal(). - */ - PROC_SLOCK(p); - mtx_lock_spin(&sc->sc_lock); PROC_UNLOCK(p); + + mtx_lock_spin(&sc->sc_lock); thread_lock(td); - PROC_SUNLOCK(p); - if (ret == 0) { - sleepq_switch(wchan, pri); - return (0); - } + if (ret != 0) + goto out; + if ((td->td_flags & (TDF_NEEDSIGCHK | TDF_NEEDSUSPCHK)) != 0) + goto catch_sig; + + sleepq_switch(wchan, pri); + return (0); + +out: /* * There were pending signals and this thread is still * on the sleep queue, remove it from the sleep queue. -- cgit v1.1