Index: kern/kern_sig.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_sig.c,v retrieving revision 1.359 diff -u -r1.359 kern_sig.c --- kern/kern_sig.c 19 Mar 2008 06:19:00 -0000 1.359 +++ kern/kern_sig.c 20 Mar 2008 08:42:20 -0000 @@ -2286,6 +2286,7 @@ FOREACH_THREAD_IN_PROC(p, td2) { thread_lock(td2); + td2->td_flags |= TDF_ASTPENDING | TDF_NEEDSUSPCHK; if ((TD_IS_SLEEPING(td2) || TD_IS_SWAPPED(td2)) && (td2->td_flags & TDF_SINTR) && !TD_IS_SUSPENDED(td2)) { Index: kern/kern_thr.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_thr.c,v retrieving revision 1.65 diff -u -r1.65 kern_thr.c --- kern/kern_thr.c 19 Mar 2008 06:19:00 -0000 1.65 +++ kern/kern_thr.c 20 Mar 2008 08:42:20 -0000 @@ -235,6 +235,8 @@ /* let the scheduler know about these things. */ sched_fork_thread(td, newtd); thread_unlock(td); + if (P_SHOULDSTOP(p)) + newtd->td_flags |= TDF_ASTPENDING | TDF_NEEDSUSPCHK; PROC_UNLOCK(p); thread_lock(newtd); if (rtp != NULL) { Index: kern/kern_thread.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_thread.c,v retrieving revision 1.272 diff -u -r1.272 kern_thread.c --- kern/kern_thread.c 20 Mar 2008 03:07:57 -0000 1.272 +++ kern/kern_thread.c 20 Mar 2008 08:42:20 -0000 @@ -549,7 +549,7 @@ if (td2 == td) continue; thread_lock(td2); - td2->td_flags |= TDF_ASTPENDING; + td2->td_flags |= TDF_ASTPENDING | TDF_NEEDSUSPCHK; if (TD_IS_INHIBITED(td2)) { switch (mode) { case SINGLE_EXIT: @@ -751,6 +751,7 @@ p->p_suspcount++; PROC_UNLOCK(p); thread_lock(td); + td->td_flags &= ~TDF_NEEDSUSPCHK; TD_SET_SUSPENDED(td); sched_sleep(td, 0); PROC_SUNLOCK(p); @@ -771,6 +772,7 @@ THREAD_LOCK_ASSERT(td, MA_OWNED); KASSERT(!TD_IS_SUSPENDED(td), ("already suspended")); p->p_suspcount++; + td->td_flags &= ~TDF_NEEDSUSPCHK; TD_SET_SUSPENDED(td); sched_sleep(td, 0); } Index: kern/subr_sleepqueue.c =================================================================== RCS file: /home/ncvs/src/sys/kern/subr_sleepqueue.c,v retrieving revision 1.50 diff -u -r1.50 subr_sleepqueue.c --- kern/subr_sleepqueue.c 19 Mar 2008 07:35:14 -0000 1.50 +++ kern/subr_sleepqueue.c 20 Mar 2008 08:42:20 -0000 @@ -391,7 +391,7 @@ * directly. */ thread_lock(td); - if ((td->td_flags & TDF_NEEDSIGCHK) == 0) { + if ((td->td_flags & (TDF_NEEDSIGCHK | TDF_NEEDSUSPCHK)) == 0) { sleepq_switch(wchan, pri); return (0); } Index: kern/subr_trap.c =================================================================== RCS file: /home/ncvs/src/sys/kern/subr_trap.c,v retrieving revision 1.302 diff -u -r1.302 subr_trap.c --- kern/subr_trap.c 12 Mar 2008 10:11:59 -0000 1.302 +++ kern/subr_trap.c 20 Mar 2008 08:42:21 -0000 @@ -96,11 +96,9 @@ thread_unlock(td); PROC_UNLOCK(p); #endif - #ifdef KTRACE KTRUSERRET(td); #endif - /* * If this thread tickled GEOM, we need to wait for the giggling to * stop before we return to userland @@ -109,21 +107,9 @@ g_waitidle(); /* - * We need to check to see if we have to exit or wait due to a - * single threading requirement or some other STOP condition. - * Don't bother doing all the work if the stop bits are not set - * at this time.. If we miss it, we miss it.. no big deal. - */ - if (P_SHOULDSTOP(p)) { - PROC_LOCK(p); - thread_suspend_check(0); /* Can suspend or kill */ - PROC_UNLOCK(p); - } - /* * Charge system time if profiling. */ if (p->p_flag & P_PROFIL) { - addupc_task(td, TRAPF_PC(frame), td->td_pticks * psratio); } /* @@ -172,9 +158,8 @@ */ thread_lock(td); flags = td->td_flags; - td->td_flags &= ~(TDF_ASTPENDING | TDF_NEEDSIGCHK | - TDF_NEEDRESCHED | TDF_ALRMPEND | TDF_PROFPEND | - TDF_MACPEND); + td->td_flags &= ~(TDF_ASTPENDING | TDF_NEEDSIGCHK | TDF_NEEDSUSPCHK | + TDF_NEEDRESCHED | TDF_ALRMPEND | TDF_PROFPEND | TDF_MACPEND); thread_unlock(td); PCPU_INC(cnt.v_trap); @@ -242,6 +227,15 @@ mtx_unlock(&p->p_sigacts->ps_mtx); PROC_UNLOCK(p); } + /* + * We need to check to see if we have to exit or wait due to a + * single threading requirement or some other STOP condition. + */ + if (flags & TDF_NEEDSUSPCHK) { + PROC_LOCK(p); + thread_suspend_check(0); + PROC_UNLOCK(p); + } userret(td, framep); mtx_assert(&Giant, MA_NOTOWNED); Index: sys/proc.h =================================================================== RCS file: /home/ncvs/src/sys/sys/proc.h,v retrieving revision 1.508 diff -u -r1.508 proc.h --- sys/proc.h 20 Mar 2008 05:51:15 -0000 1.508 +++ sys/proc.h 20 Mar 2008 08:42:25 -0000 @@ -309,7 +309,7 @@ #define TDF_TIMOFAIL 0x00001000 /* Timeout from sleep after we were awake. */ #define TDF_UNUSED2000 0x00002000 /* --available-- */ #define TDF_UPIBLOCKED 0x00004000 /* Thread blocked on user PI mutex. */ -#define TDF_UNUSED15 0x00008000 /* --available-- */ +#define TDF_NEEDSUSPCHK 0x00008000 /* Thread may need to suspend. */ #define TDF_NEEDRESCHED 0x00010000 /* Thread needs to yield. */ #define TDF_NEEDSIGCHK 0x00020000 /* Thread may need signal delivery. */ #define TDF_XSIG 0x00040000 /* Thread is exchanging signal under trace */