diff options
author | davidxu <davidxu@FreeBSD.org> | 2008-10-23 07:55:38 +0000 |
---|---|---|
committer | davidxu <davidxu@FreeBSD.org> | 2008-10-23 07:55:38 +0000 |
commit | 2062caca2494bf113adefa9ca01f9f5fb24ad7b9 (patch) | |
tree | 0f85351fa5ffde7cf121d1e0f3f5e83ff415f868 /sys/kern/subr_sleepqueue.c | |
parent | b20c19bc667aef513fa9f5449df2d4a833e42d3d (diff) | |
download | FreeBSD-src-2062caca2494bf113adefa9ca01f9f5fb24ad7b9.zip FreeBSD-src-2062caca2494bf113adefa9ca01f9f5fb24ad7b9.tar.gz |
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.
Diffstat (limited to 'sys/kern/subr_sleepqueue.c')
-rw-r--r-- | sys/kern/subr_sleepqueue.c | 25 |
1 files changed, 13 insertions, 12 deletions
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. |