diff options
author | kib <kib@FreeBSD.org> | 2009-07-14 22:52:46 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2009-07-14 22:52:46 +0000 |
commit | c7441b67e68fb8dbdec2ca853f77acf72e7cf0e9 (patch) | |
tree | b51305b6f0c522d37eac747f4cbb29242078546b /sys/kern/subr_sleepqueue.c | |
parent | aa9063dc970560b1ab26b34f292e63ad270cb4c4 (diff) | |
download | FreeBSD-src-c7441b67e68fb8dbdec2ca853f77acf72e7cf0e9.zip FreeBSD-src-c7441b67e68fb8dbdec2ca853f77acf72e7cf0e9.tar.gz |
Add new msleep(9) flag PBDY that shall be specified together with
PCATCH, to indicate that thread shall not be stopped upon receipt of
SIGSTOP until it reaches the kernel->usermode boundary.
Also change thread_single(SINGLE_NO_EXIT) to only stop threads at
the user boundary unconditionally.
Tested by: pho
Reviewed by: jhb
Approved by: re (kensmith)
Diffstat (limited to 'sys/kern/subr_sleepqueue.c')
-rw-r--r-- | sys/kern/subr_sleepqueue.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/sys/kern/subr_sleepqueue.c b/sys/kern/subr_sleepqueue.c index 01fcc73..b3ae6fd 100644 --- a/sys/kern/subr_sleepqueue.c +++ b/sys/kern/subr_sleepqueue.c @@ -341,6 +341,8 @@ sleepq_add(void *wchan, struct lock_object *lock, const char *wmesg, int flags, if (flags & SLEEPQ_INTERRUPTIBLE) { td->td_flags |= TDF_SINTR; td->td_flags &= ~TDF_SLEEPABORT; + if (flags & SLEEPQ_STOP_ON_BDRY) + td->td_flags |= TDF_SBDRY; } thread_unlock(td); } @@ -378,7 +380,7 @@ sleepq_catch_signals(void *wchan, int pri) struct thread *td; struct proc *p; struct sigacts *ps; - int sig, ret; + int sig, ret, stop_allowed; td = curthread; p = curproc; @@ -395,6 +397,8 @@ sleepq_catch_signals(void *wchan, int pri) sleepq_switch(wchan, pri); return (0); } + stop_allowed = (td->td_flags & TDF_SBDRY) ? SIG_STOP_NOT_ALLOWED : + SIG_STOP_ALLOWED; thread_unlock(td); mtx_unlock_spin(&sc->sc_lock); CTR3(KTR_PROC, "sleepq catching signals: thread %p (pid %ld, %s)", @@ -402,7 +406,7 @@ sleepq_catch_signals(void *wchan, int pri) PROC_LOCK(p); ps = p->p_sigacts; mtx_lock(&ps->ps_mtx); - sig = cursig(td); + sig = cursig(td, stop_allowed); if (sig == 0) { mtx_unlock(&ps->ps_mtx); ret = thread_suspend_check(1); @@ -560,7 +564,7 @@ sleepq_check_signals(void) /* We are no longer in an interruptible sleep. */ if (td->td_flags & TDF_SINTR) - td->td_flags &= ~TDF_SINTR; + td->td_flags &= ~(TDF_SINTR | TDF_SBDRY); if (td->td_flags & TDF_SLEEPABORT) { td->td_flags &= ~TDF_SLEEPABORT; @@ -682,7 +686,7 @@ sleepq_resume_thread(struct sleepqueue *sq, struct thread *td, int pri) td->td_wmesg = NULL; td->td_wchan = NULL; - td->td_flags &= ~TDF_SINTR; + td->td_flags &= ~(TDF_SINTR | TDF_SBDRY); CTR3(KTR_PROC, "sleepq_wakeup: thread %p (pid %ld, %s)", (void *)td, (long)td->td_proc->p_pid, td->td_name); |