diff options
author | jeff <jeff@FreeBSD.org> | 2008-03-19 07:35:14 +0000 |
---|---|---|
committer | jeff <jeff@FreeBSD.org> | 2008-03-19 07:35:14 +0000 |
commit | d43ad8d37e3c67a58f6d5917a4f252f0a177f652 (patch) | |
tree | 5e128b7a18ed5eef618ac65241762a3e2ba72bbe | |
parent | d4862a02d2a48532593512bf78aafae99ce4789e (diff) | |
download | FreeBSD-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.
-rw-r--r-- | sys/kern/subr_sleepqueue.c | 16 |
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); |