summaryrefslogtreecommitdiffstats
path: root/sys/kern/subr_sleepqueue.c
diff options
context:
space:
mode:
authordavidxu <davidxu@FreeBSD.org>2008-10-23 07:55:38 +0000
committerdavidxu <davidxu@FreeBSD.org>2008-10-23 07:55:38 +0000
commit2062caca2494bf113adefa9ca01f9f5fb24ad7b9 (patch)
tree0f85351fa5ffde7cf121d1e0f3f5e83ff415f868 /sys/kern/subr_sleepqueue.c
parentb20c19bc667aef513fa9f5449df2d4a833e42d3d (diff)
downloadFreeBSD-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.c25
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.
OpenPOWER on IntegriCloud