Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.1 6/24/83; site bu-cs.UUCP Path: utzoo!watmath!clyde!burl!ulysses!allegra!mit-eddie!genrad!panda!talcott!harvard!bu-cs!root From: root@bu-cs.UUCP (Barry Shein) Newsgroups: net.emacs Subject: Re: CCA Emacs Redisplay Bug Fix Message-ID: <203@bu-cs.UUCP> Date: Wed, 27-Feb-85 18:46:17 EST Article-I.D.: bu-cs.203 Posted: Wed Feb 27 18:46:17 1985 Date-Received: Fri, 1-Mar-85 20:49:12 EST References: <1076@godot.UUCP> Organization: Boston Univ Comp. Sci. Lines: 69 In a similar vein, I noticed that running CCA EMACS on our student VAX750 (4.2bsd) seemed to be very uneven and creating a fair amount of load. I began by studying the main loop that reads in keystrokes and noticed the following: characters are read in 1 at a time with a read(0,&c,1) type statement there is polling for typeahead existence via empty(0) calls which invokes ioctl(0,FIONREAD,&n) This causes a lot of calls to the system per keystroke. Read the code and consider what occurs when all your users are using terminals with multi-character function keys (eg. VT100s, VT200s) Solution (maybe better put, approach): [this applies to 4.2bsd] replace the read(0,&c,1) call with a call to a routine rdchar(0) which buffers up as many input chars as it can (a little _filbuf/getc routine really.) Set the character count held in the buffer into a global. Now empty(0) becomes simply a test against this character count which isn't as accurate but the penalty for being wrong is much less than the penalty for so many sys calls NOW for the thing that makes it work: use a select() call in rdchar to delay 1/10 of a second: (PSUEDO-CODE HERE) again: if(n_inbuf-- > 0) return(buf[nxtchar++]) else { t->tv_sec = 0 ; t->tv_usec = NTENTHS * 100000 ; select(0,0,0,0,t) ; /* cast these */ if((n_inbuf = read(0,MAXBUF,buf)) <= 0) ...err nxtchar = 0 ; goto again ; } This will tend to pick up function keys in one shot, sometimes more than one if the person is hammering an arrow key or some such. empty becomes: return(!n_inbuf) ; Just for generality's sake, I made the number of 1/10s of seconds available as an EMACS var to the user (test for zero before the select()) Seems to help although these things are very hard to measure. That system was definitely getting too many syscalls as judged by vmstat, now seems better. On a SYSV system one can just use the MINchars, MINtime features of ~CANON for similar effect. Yes, I still get the effect of pause while a lot of typing coming in and then just display entire update. I have found that 2 or 3 1/10s of a second is tolerable. It is possible I am crocked here I suppose...anyone got a good way to quantify the supposed advantage? I am just going by common sense and observation which is very dangerous in performance issues. P.S. changes are in e_main.c and e_io.c -Barry Shein, Boston University