Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!unmvax!pprg.unm.edu!hc!lll-winken!uunet!auspex!guy From: guy@auspex.UUCP (Guy Harris) Newsgroups: comp.dcom.modems Subject: Re: Telebit transfer rate problem Message-ID: <1330@auspex.UUCP> Date: 30 Mar 89 19:47:26 GMT References: <640@island.uu.net> <64160@pyramid.pyramid.com> <1553@neoucom.UUCP> Reply-To: guy@auspex.UUCP (Guy Harris) Organization: Auspex Systems, Santa Clara Lines: 64 >It has been my experience that quite a few implementations of Unix >have pretty crummy tty drivers, especially on the receive side of >the coin. The lack of optimization is probably due to the fact >that most software engineers forget that anything other than a >human being might be typing characters in. Most of the tty drivers >generate an CPU interrupt per character received. That's not a software engineer's problem, that's a hardware engineer's problem - the serial port hardware doesn't buffer up characters. >With Unix this is nasty, as it might mean that several context switches >take place for each character received. That has nothing to do with the number of interrupts; in UNIX systems, interrupts tend to be serviced in whatever context was running at the time the interrupt occurred. Even if you have a streams driver, streams modules would tend to be run in the same context. The problem is that you get a *wakeup* for every character received; that's where the context switches come from. There are at least two ways around this: 1) When you receive a character, buffer it a while in the driver and see whether any more come in just after it. Only wake up the process waiting for input when enough characters come in, or more than some amount of time elapses after "the last one" comes in. SunOS, for example, does this on its CPU serial ports; when running high-speed UUCP input (38.4KB), the difference between receiving on a CPU serial port and, say, an ALM-1 is noticeable. SunOS 4.0 does this on all serial ports, in order to fix some problems with streams flow control. 4.0 had some other problems with streams flow control (limits being set too low, and CPU serial port driver sending "runt" streams messages upstream); 4.0.1 fixes those. This significantly reduced the CPU overhead for 19.2KB receiving on ALM-1 ports (ALM-1s don't run at 38.4), for example. (Also, converting to streams reduced CPU overhead some more - I suspect it was because the old line discipline interface required one procedure call from the driver to the line discipline on every character, while the streams code requires one call per streams message, and if the characters are coming in thick and fast the driver tries to pack 16 or so characters per streams module.) 2) If you have VMIN and VTIME support in your tty driver, set VMIN and VTIME to do a similar sort of buffering (VMIN specifies "enough characters", and VTIME specifies "some amount of time"). 4.4BSD should give you VMIN and VTIME, since it'll have a POSIX-compliant tty driver. Perhaps the 4.4BSD UUCP will use VMIN and VTIME. To some degree, sticking in delays into the receive code UUCP gives the same result; I think the 4.3BSD UUCP does so. (SunOS 4.0 already gives you VMIN and VTIME, although the UUCPs first tested were the current SunOS UUCPs, which still use the old tty driver "ioctl"s and thus don't use VMIN nor VTIME. As I remember, using the version of Honey DanBer UUCP slated for 4.1, which *does* use VMIN and VTIME, the CPU overhead dropped a bit more.)