summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorjeff <jeff@FreeBSD.org>2008-03-19 07:35:14 +0000
committerjeff <jeff@FreeBSD.org>2008-03-19 07:35:14 +0000
commitd43ad8d37e3c67a58f6d5917a4f252f0a177f652 (patch)
tree5e128b7a18ed5eef618ac65241762a3e2ba72bbe /sys
parentd4862a02d2a48532593512bf78aafae99ce4789e (diff)
downloadFreeBSD-src-d43ad8d37e3c67a58f6d5917a4f252f0a177f652.zip
FreeBSD-src-d43ad8d37e3c67a58f6d5917a4f252f0a177f652.tar.gz
- At the top of sleepq_catch_signals() lock the thread and check TDF_NEEDSIGCHK
before doing the very expensive cursig() and related locking. NEEDSIGCHK is updated whenever our signal mask change or when a signal is delivered and should be sufficient to avoid the more expensive tests. This eliminates another source of PROC_LOCK contention in multithreaded programs.
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/subr_sleepqueue.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/sys/kern/subr_sleepqueue.c b/sys/kern/subr_sleepqueue.c
index fe3b5e9..e12ef6e 100644
--- a/sys/kern/subr_sleepqueue.c
+++ b/sys/kern/subr_sleepqueue.c
@@ -385,12 +385,20 @@ sleepq_catch_signals(void *wchan, int pri)
sc = SC_LOOKUP(wchan);
mtx_assert(&sc->sc_lock, MA_OWNED);
MPASS(wchan != NULL);
+ /*
+ * See if there are any pending signals for this thread. If not
+ * we can switch immediately. Otherwise do the signal processing
+ * directly.
+ */
+ thread_lock(td);
+ if ((td->td_flags & TDF_NEEDSIGCHK) == 0) {
+ sleepq_switch(wchan, pri);
+ return (0);
+ }
+ thread_unlock(td);
+ mtx_unlock_spin(&sc->sc_lock);
CTR3(KTR_PROC, "sleepq catching signals: thread %p (pid %ld, %s)",
(void *)td, (long)p->p_pid, td->td_name);
-
- mtx_unlock_spin(&sc->sc_lock);
-
- /* See if there are any pending signals for this thread. */
PROC_LOCK(p);
ps = p->p_sigacts;
mtx_lock(&ps->ps_mtx);
OpenPOWER on IntegriCloud