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);
  }