[net.bugs.usg] Horrible ugliness in V.2 readi/writei.

chris@neology.OZ (Chris Maltby) (07/25/85)

I just had enormous problems with writing the line printer part
of a dmf32 driver. I couldn't work out why it never did anything,
and behaved badly in general.  The problem turned out to be this
revolting code in the 5.2 readi/writei code:

	if (cdevsw[major(dev)].d_tty != NULL)
	{
		tp = &cdevsw[major(dev)].d_tty[minor(dev)];
		(*linesw[tp->t_ldisc].l_write)(tp);
	}
	else
		(*cdevsw[major(dev)].d_write)(minor(dev));

This part of the system has no right to assume what the code in a
driver's read/write routine does, even if it seems to be a tty driver.
It saves exactly one function call per tty write (when it's correct),
which is b*gger-all.  There is a much bigger scope for optimising
performance by trying harder to eliminate single char (or small) writes
in programs. You could gain as much by removing the common code of rdwr
and puuting it into both read and write, but they didn't think of
this.

Of course, I was using the top bit of minor(dev) to mean something
special.  You can understand the horrible bug it caused.  I don't know
where I would have been without the source.

P.S. I wasn't helped by DEC's DMF32 manual which states that the lp DMA
byte count register contains "a byte count". It REALLY means "a two's
complement byte count". This is different from the async DMA byte count,
just to make it that little bit harder...

Chris Maltby - Neology Ltd.  (chris@neology.oz, seismo!neology.oz!chris)

phil@qfdts.oz (Phil Chadwick) (07/30/85)

In article <150@neology.OZ> chris@neology.OZ (Chris Maltby) says:

    >The problem turned out to be this
    >revolting code in the 5.2 readi/writei code:
    >
    >	if (cdevsw[major(dev)].d_tty != NULL)
    >	{
    >		tp = &cdevsw[major(dev)].d_tty[minor(dev)];
    >		(*linesw[tp->t_ldisc].l_write)(tp);
    >	}
    >	else
    >		(*cdevsw[major(dev)].d_write)(minor(dev));
    >
    >This part of the system has no right to assume what the code in a
    >driver's read/write routine does, even if it seems to be a tty driver.

Here, here!

I tripped over this some time ago while writing a pseudo dn11 driver.
Code put into the tty's write routine did nothing (not surprising -
once you realise it's being bypassed).  To the best of my recollection
it's been there since the very first System V release.

----
Phil Chadwick		  Australia: (07) 2296500
Department of Forestry	  International: +61 7 2296500
PO Box 5		  ACSnet: phil@qfdts.oz
Brisbane, Roma Street	  ARPA: decvax!mulga!qfdts.oz!phil@UCB-VAX.ARPA
AUSTRALIA	4001	  UUCP: {decvax,vax135,eagle,pesnta}!mulga!qfdts.oz!phil