[net.sources] WMS NEWLETTER #3

system@asuvax.UUCP (Marc Lesure) (10/29/85)

	    WMS 1.7b NEWSLETTER #3, 10/28/85 (MAJOR UPDATES)	[net.sources]

This is a supplemental newsletter for users of the ASU Window Management System.

These updates affect code performance and should be tended to ASAP. 
The previous method of polled I/O is replaced by a synchronous interrupt 
driven scheme (based on select(2)).  This results in improved performance 
due to significantly reduced system loading.

Major Updates follow:


======= File: release/makefile

======= Change the line:
v			= 1.7b # version
======= to:
v			= 1.7c # version


======= File: release/source/msh/msh.c

======= Near the top of the file, change:
#include <sys/timeb.h>
======= to:
#include <sys/time.h>

======= After the line:
static	bool	C_result;
=======	add:
static	short	delta_shell = 0;

======= Replace the entire procedure slave_driver() by:
public	slave_driver()
/* Poll slave 'slave_index'. Send any and all input thus received to the 
 * remote window manager for output to its window. 
 */
{
	int result;
	reg slave_t *sp, *tsp;
	char chb[AMAXCBUF]; reg char *chbp = chb;
	unsigned int m_mask; /* current master mask */ 
	unsigned int s_mask; /* current slave mask */
	static unsigned int sav_s_mask = 0; /* static mask */
	static unsigned int pre_s_mask = 0; /* previous mask */
	static int skip = AMAXSLAVES << 4; /* ad hoc */
	/* skip select @ init, when activity continuous & every delta_shell */

	m_mask = 1; /* master input fd 0 */
	if (pre_s_mask == 0) { /* if no more slave leftovers */
		if (delta_shell) { short i; /* recompute static mask */
			skip = (delta_shell--) << 4; /* ad hoc */
			sav_s_mask = 0;
			for (i = 0; i < MAXSLAVES; i++)
				if (slave[i].pid != NIL) 
					sav_s_mask |= (1 << slave[i].pty.f); 
		}
		s_mask = sav_s_mask;
		if (skip == 0) {
			int mask;
			struct timeval tout;
			long t = (long) time(0); 

			mask = m_mask|s_mask;
			tout.tv_sec = (long) 10000000;
			tout.tv_usec = (long) 0;
			/* block until master input or slave output ready */
			select(20, &mask, 0, 0, &tout); /* 20 => OPEN_MAX */
			m_mask = 01 & mask;
			s_mask = ((~0) << 1) & mask;
			if ((long) time(0) - t < 2) skip = AMAXSLAVES << 4;
		} else skip--;
		pre_s_mask = s_mask;
	}
	if (m_mask == 1) master_driver(); /* even if leftovers */
	if (pre_s_mask == 0) return; /* no slave to do this time */
	/* find next slave */
	while (((1 << slave[slave_index = ((++slave_index) % MAXSLAVES)].pty.f) 
	    & pre_s_mask) == 0) ;
	if ((sp = &slave[slave_index])->pid == NIL) { /* due to do_DS */
		pre_s_mask = 0;
		return;
	}
	pre_s_mask &= (~(1 << sp->pty.f)); /* drop it from leftover set */
	/* do only one slave per call => leftovers */
	if ((result = get_slave(sp,chbp,MAXCBUF)) > 0) {
		/* KLUDGE: If the slave has just been created, 
		 * now is the time to tell it about TERM
		 */
		if (sp->rs_pending) {
			/* for do_RS */
			tsp = islave;
			islave = sp;
			sp->rs_pending = FALSE;
			do_RS(sp->rs_tc);
			islave = tsp;
		}
		/* here is the output fragment packet header */
		goto_win(&(sp->label));
		put_master(chbp,result);
	}
} /* slave_driver */

======= Add to the beginning of procedures do_CU() and do_DS():
	++delta_shell;

======= In function get_slave(), add:
		++delta_shell;
======= just before the line:
		len = (-1);

======= In procedure set_state(), change:
	ioctl(f,TIOCGETD,&(ttyp->d));
======= to:
	ioctl(f,TIOCSETD,&(ttyp->d));


======= File: release/mant/wms.t

======= After the lines:
This parameter does not apply to the current input shell when an echo is
pending.
======= add:
.PP
NOTE: The MAXNOPOLLS parameter has been rendered useless in versions 1.7c and
later due to the substitution of interrupt driven I/O for polled I/O.


======= File: release/public/termcap

======= Replace the entire "ansi" entry by:
0|ansi|ANSI|dec vt100 superset :\
	:am:al=8\E[1L:\
	:bc=2^H:\
	:cd=50\E[J:ce=8\E[K:cl=50\E[H\E[2J:cm=15\E[%i%d;%dH:co#80:cr=5^M:\
		:cs=15\E[%i%d;%dr:\
	:dc=5\E[1P:dl=5\E[1M:dm=:do=8^J:\
	:ed=:ei=:\
	:ho=10\E[H:\
	:ic=5\E[1@:im=:is=50\E[2J\E[H:\
	:k0=\EOP:k1=\EOQ:k2=\EOR:k3=\EOS:k4=\EOT:\
	:k5=\EOU:k6=\EOV:k7=\EOW:k8=\EOX:k9=\EOY:\
	:kd=\EOB:ke=\E[?1l\E>:kl=\EOD:kr=\EOC:ks=\E[?1h\E=:ku=\EOA:\
	:li#24:\
	:nd=2\E[C:nl=8^J:\
	:pt:\
	:se=2\E[m:sf=10\ED:sg#0:so=2\E[7m:sr=10\EM:\
	:ue=2\E[m:ug#0:us=2\E[4m:up=8\E[A:\
	:ve=:vs=:\
	:we=50\E[2J\E[1;24r\E[H:ws=50\E[2J\E[1;24r\E[H:


======= File: release/source/NOTES

======= Add to the end of the file the lines:
------------------------------------------------------------------------------
According to the select system call documentation, a call of the form:
    select(nbits,&inmask,&outmask,&excmask,(struct timeval *) 0)
is supposed to block until something is ready.  What really happens is that
the call returns immediately (without blocking).  That is why the method 
(tout.tv_sec = ...) was used (in slave_driver).  This should, of course,
be intuitively obvious even to the casual observer off the street.  :-(




======= End of Updates.  Summary:
- Change version.
- Add code to make IO interrupt driven.
- Correct typo in setstate().
- Modify wms manual to account for I/O change.
- Patch "ansi" entry: cleanup & add more delay where experience has revealed
- delay timing problems with vi under certain circumstances.
- Add to source/NOTES.
- Thanks to Mario Wolczko et al (..!ukc!edcaad!mupsy!mucs!miw) for suggesting
- use of select system call.


George Nelan 				UUCP:	
Engineering Research Center (ERC 207)	...{ucbvax,ihnp4}!arizona!asuvax!nelan
Arizona State University		...ihnp4!noao!terak!asuvax!nelan
Tempe, Arizona, USA, 85287 		CSNET:	
(602)-965-2791 				nelan@asu