Subject: vi &
To: None <tech-smp@netbsd.org>
From: enami tsugutomo <enami@sm.sony.co.jp>
List: tech-smp
Date: 06/19/2001 10:09:12
Here is my work around for `vi &' problem which causes locking against
myself on smp system.
At least whether sleep condition met is kept and checked in p_wchan,
so i guess this will work. Or, am I missing something?
enami.
Index: kern_sig.c
===================================================================
RCS file: /export/netbsd/cvsroot/syssrc/sys/kern/kern_sig.c,v
retrieving revision 1.114
diff -c -r1.114 kern_sig.c
*** kern_sig.c 2001/06/13 16:06:28 1.114
--- kern_sig.c 2001/06/19 00:57:50
***************
*** 999,1004 ****
--- 999,1005 ----
issignal(struct proc *p)
{
int s, signum, prop;
+ int dolock = (p->p_flag & P_SINTR) == 0, locked = !dolock;
sigset_t ss;
for (;;) {
***************
*** 1008,1013 ****
--- 1009,1016 ----
signum = firstsig(&ss);
if (signum == 0) { /* no signal to send */
p->p_sigctx.ps_sigcheck = 0;
+ if (locked && dolock)
+ SCHED_LOCK(s);
return (0);
}
/* take the signal! */
***************
*** 1028,1039 ****
*/
p->p_xstat = signum;
if ((p->p_flag & P_FSTRACE) == 0)
! psignal(p->p_pptr, SIGCHLD);
! SCHED_LOCK(s);
proc_stop(p);
mi_switch(p);
SCHED_ASSERT_UNLOCKED();
! splx(s);
/*
* If we are no longer being traced, or the parent
--- 1031,1046 ----
*/
p->p_xstat = signum;
if ((p->p_flag & P_FSTRACE) == 0)
! psignal1(p->p_pptr, SIGCHLD, dolock);
! if (dolock)
! SCHED_LOCK(s);
proc_stop(p);
mi_switch(p);
SCHED_ASSERT_UNLOCKED();
! if (dolock)
! splx(s);
! else
! dolock = 1;
/*
* If we are no longer being traced, or the parent
***************
*** 1095,1106 ****
break; /* == ignore */
p->p_xstat = signum;
if ((p->p_pptr->p_flag & P_NOCLDSTOP) == 0)
! psignal(p->p_pptr, SIGCHLD);
! SCHED_LOCK(s);
proc_stop(p);
mi_switch(p);
SCHED_ASSERT_UNLOCKED();
! splx(s);
break;
} else if (prop & SA_IGNORE) {
/*
--- 1102,1117 ----
break; /* == ignore */
p->p_xstat = signum;
if ((p->p_pptr->p_flag & P_NOCLDSTOP) == 0)
! psignal1(p->p_pptr, SIGCHLD, dolock);
! if (dolock)
! SCHED_LOCK(s);
proc_stop(p);
mi_switch(p);
SCHED_ASSERT_UNLOCKED();
! if (dolock)
! splx(s);
! else
! dolock = 1;
break;
} else if (prop & SA_IGNORE) {
/*
***************
*** 1137,1142 ****
--- 1148,1155 ----
/* leave the signal for later */
sigaddset(&p->p_sigctx.ps_siglist, signum);
CHECKSIGS(p);
+ if (locked && dolock)
+ SCHED_LOCK(s);
return (signum);
}