Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/kern Two fixes:
details: https://anonhg.NetBSD.org/src/rev/8b369bb8e047
branches: trunk
changeset: 542804:8b369bb8e047
user: nathanw <nathanw%NetBSD.org@localhost>
date: Fri Feb 07 21:43:18 2003 +0000
description:
Two fixes:
* Change the semantics of proc_unstop() slightly, so that it is
responsible for making all stopped LWPs runnable, instead of
all-but-one. Return value is a LWP that can be interrupted if doing
so is necessary to take a signal. Adjust callers of proc_stop() to
the new, simpler semantics.
* When a non-continue signal is delivered to a stopped process and
there is a LWP sleeping interruptably, call setrunnable() (by way
of the 'out:' target in psignal1) instead of calling unsleep() so
that it becomes LSSTOP in issignal() and continuable by
proc_unstop(). Addresses PR kern/19990 by Martin Husemann, with
suggestions from enami tsugutomo.
diffstat:
sys/kern/kern_sig.c | 65 ++++++++++++++++++++++++++--------------------------
1 files changed, 32 insertions(+), 33 deletions(-)
diffs (129 lines):
diff -r 274b72637397 -r 8b369bb8e047 sys/kern/kern_sig.c
--- a/sys/kern/kern_sig.c Fri Feb 07 21:00:43 2003 +0000
+++ b/sys/kern/kern_sig.c Fri Feb 07 21:43:18 2003 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_sig.c,v 1.132 2003/02/07 09:02:14 jdolecek Exp $ */
+/* $NetBSD: kern_sig.c,v 1.133 2003/02/07 21:43:18 nathanw Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1991, 1993
@@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.132 2003/02/07 09:02:14 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.133 2003/02/07 21:43:18 nathanw Exp $");
#include "opt_ktrace.h"
#include "opt_compat_sunos.h"
@@ -973,7 +973,6 @@
l = proc_unstop(p);
if (l)
goto runfast;
- /* XXX should this be possible? */
goto out;
}
@@ -996,16 +995,8 @@
sigdelset(&p->p_sigctx.ps_siglist,
signum);
l = proc_unstop(p);
- /*
- * XXX see note in proc_unstop(). SIGKILL
- * XXX and SIGCONT have conflicting needs.
- */
- if (l && (l->l_stat == LSSLEEP))
- l = NULL;
if (l && (action == SIG_CATCH))
goto runfast;
- if (l)
- goto run;
goto out;
}
@@ -1019,14 +1010,15 @@
}
/*
- * If process is sleeping interruptibly, then
- * simulate a wakeup so that when it is
- * continued, it will be made runnable and can
- * look at the signal. But don't make the
- * process runnable, leave it stopped.
+ * If a lwp is sleeping interruptibly, then
+ * wake it up; it will run until the kernel
+ * boundary, where it will stop in issignal(),
+ * since p->p_stat is still SSTOP. When the
+ * process is continued, it will be made
+ * runnable and can look at the signal.
*/
if (l)
- unsleep(l);
+ goto run;
goto out;
} else {
/* Else what? */
@@ -1364,11 +1356,20 @@
sched_wakeup((caddr_t)p->p_pptr);
}
+/*
+ * Given a process in state SSTOP, set the state back to SACTIVE and
+ * move LSSTOP'd LWPs to LSSLEEP or make them runnable.
+ *
+ * If no LWPs ended up runnable (and therefore able to take a signal),
+ * return a LWP that is sleeping interruptably. The caller can wake
+ * that LWP up to take a signal.
+ */
struct lwp *
proc_unstop(p)
struct proc *p;
{
struct lwp *l, *lr = NULL;
+ int cantake = 0;
SCHED_ASSERT_LOCKED();
@@ -1378,28 +1379,26 @@
*/
p->p_stat = SACTIVE;
- /*
- * For the benefit of SIGKILL, return the idle LWP if there's
- * nothing better (and if there is an idle LWP, there
- * shouldn't be anything better.
- * XXX This is bad for SIGCONT; SIGSTOP/SIGCONT shouldn't
- * XXX noticably affect the state of a process, idling or
- * XXX not. We work around this in the SIGCONT handling in
- * XXX psignal().
- */
- if (p->p_flag & P_SA)
+ if (p->p_flag & P_SA) {
lr = p->p_sa->sa_idle; /* OK if this is NULL. */
+ cantake = 1;
+ }
LIST_FOREACH(l, &p->p_lwps, l_sibling) {
+ if (l->l_stat == LSRUN)
+ cantake = 1;
if (l->l_stat != LSSTOP)
continue;
- if (l->l_wchan == NULL) {
- if (lr == NULL)
+ if (l->l_wchan != NULL) {
+ l->l_stat = LSSLEEP;
+ if ((cantake == 0) && (l->l_flag & L_SINTR)) {
lr = l;
- else if (l != lr)
- setrunnable(l);
- } else
- l->l_stat = LSSLEEP;
+ cantake = 1;
+ }
+ } else {
+ setrunnable(l);
+ cantake = 1;
+ }
}
return lr;
Home |
Main Index |
Thread Index |
Old Index