Index: kern/kern_sig.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_sig.c,v retrieving revision 1.353 diff -u -r1.353 kern_sig.c --- kern/kern_sig.c 18 Dec 2007 20:39:13 -0000 1.353 +++ kern/kern_sig.c 30 Dec 2007 02:00:12 -0000 @@ -557,6 +557,26 @@ } /* + * Check for signals without the proc lock before we switch. The more + * expensive cursig() must be called if this check returns true. Otherwise + * the test is only valid until the thread lock is dropped at which time + * new signals may be delivered. + */ +int +peeksig(struct thread *td) +{ + sigset_t sigpending; + + THREAD_LOCK_ASSERT(td, MA_NOTOWNED); + + sigpending = td->td_sigqueue.sq_signals; + SIGSETNAND(sigpending, td->td_sigmask); + if (SIGISEMPTY(sigpending)) + return (0); + return (1); +} + +/* * Arrange for ast() to handle unmasked pending signals on return to user * mode. This must be called whenever a signal is added to td_sigqueue or * unmasked in td_sigmask. Index: kern/subr_sleepqueue.c =================================================================== RCS file: /home/ncvs/src/sys/kern/subr_sleepqueue.c,v retrieving revision 1.41 diff -u -r1.41 subr_sleepqueue.c --- kern/subr_sleepqueue.c 14 Nov 2007 06:51:33 -0000 1.41 +++ kern/subr_sleepqueue.c 30 Dec 2007 02:00:12 -0000 @@ -383,8 +383,13 @@ MPASS(wchan != NULL); CTR3(KTR_PROC, "sleepq catching signals: thread %p (pid %ld, %s)", (void *)td, (long)p->p_pid, td->td_name); - + thread_lock(td); + if (peeksig(td) == 0 && !(td->td_flags & TDF_INTERRUPT)) { + sleepq_switch(wchan); + return (0); + } mtx_unlock_spin(&sc->sc_lock); + thread_unlock(td); /* See if there are any pending signals for this thread. */ PROC_LOCK(p); Index: kern/subr_lock.c =================================================================== RCS file: /home/ncvs/src/sys/kern/subr_lock.c,v retrieving revision 1.19 diff -u -r1.19 subr_lock.c --- kern/subr_lock.c 15 Dec 2007 23:13:31 -0000 1.19 +++ kern/subr_lock.c 30 Dec 2007 02:00:12 -0000 @@ -150,11 +150,11 @@ */ struct lock_prof { SLIST_ENTRY(lock_prof) link; + struct lock_class *class; const char *file; const char *name; int line; int ticks; - const char *type; uintmax_t cnt_max; uintmax_t cnt_tot; uintmax_t cnt_wait; @@ -249,6 +249,7 @@ enabled = lock_prof_enable; lock_prof_enable = 0; + pause("lpreset", hz / 100); for (cpu = 0; cpu <= mp_maxid; cpu++) { lpc = lp_cpu[cpu]; for (i = 0; i < LPROF_CACHE_SIZE; i++) { @@ -277,7 +278,7 @@ lp->cnt_cur == 0 ? (uintmax_t)0 : lp->cnt_wait / (lp->cnt_cur * 1000), (uintmax_t)0, lp->cnt_contest_locking, - p, lp->line, lp->type, lp->name); + p, lp->line, lp->class->lc_name, lp->name); } static void @@ -290,7 +291,7 @@ dst->file = match->file; dst->line = match->line; - dst->type = match->type; + dst->class = match->class; dst->name = match->name; for (cpu = 0; cpu <= mp_maxid; cpu++) { @@ -301,7 +302,7 @@ if (l->ticks == t) continue; if (l->file != match->file || l->line != match->line || - l->name != match->name || l->type != match->type) + l->name != match->name) continue; l->ticks = t; if (l->cnt_max > dst->cnt_max) @@ -342,11 +343,15 @@ static int multiplier = 1; struct sbuf *sb; int error, cpu, t; + int enabled; retry_sbufops: sb = sbuf_new(NULL, NULL, LPROF_SBUF_SIZE * multiplier, SBUF_FIXEDLEN); sbuf_printf(sb, "\n%6s %12s %12s %11s %5s %5s %12s %12s %s\n", "max", "total", "wait_total", "count", "avg", "wait_avg", "cnt_hold", "cnt_lock", "name"); + enabled = lock_prof_enable; + lock_prof_enable = 0; + pause("lpreset", hz / 100); t = ticks; for (cpu = 0; cpu <= mp_maxid; cpu++) { if (lp_cpu[cpu] == NULL) @@ -359,6 +364,7 @@ goto retry_sbufops; } } + lock_prof_enable = enabled; sbuf_finish(sb); error = SYSCTL_OUT(req, sbuf_data(sb), sbuf_len(sb) + 1); @@ -436,7 +442,7 @@ SLIST_REMOVE_HEAD(&type->lpt_lpalloc, link); lp->file = p; lp->line = line; - lp->type = lo->lo_type; + lp->class = LOCK_CLASS(lo); lp->name = lo->lo_name; SLIST_INSERT_HEAD(&type->lpt_hash[hash], lp, link); return (lp); Index: sys/signalvar.h =================================================================== RCS file: /home/ncvs/src/sys/sys/signalvar.h,v retrieving revision 1.78 diff -u -r1.78 signalvar.h --- sys/signalvar.h 5 Nov 2007 11:36:16 -0000 1.78 +++ sys/signalvar.h 30 Dec 2007 02:00:12 -0000 @@ -315,6 +315,7 @@ * Machine-independent functions: */ int cursig(struct thread *td); +int peeksig(struct thread *td); void execsigs(struct proc *p); void gsignal(int pgid, int sig); void killproc(struct proc *p, char *why);