thomson@uthub.UUCP (Brian Thomson) (06/19/84)
Index: /sys/sys/tty_pty.c 4.2BSD Fix Description: Oink oink! That is the sound that data makes as it travels through 4.2BSD's pseudo-tty driver. Even in the high-volume direction (slave to controller) there is a great deal of code executed per-character. On our otherwise idle 750 I measured the maximum pty throughput at 5K chars/sec.; after applying the following mods it reached 30K chars/sec. If your machine is often accessed through rlogin(1c) this can mean considerable savings in system-state CPU time. Repeat-By: Run this program and use iostat(1) to see what your character rate is. #include <sys/types.h> char buf[1024]; int wsize = 1024; main() { int csock, dsock, i; for(i=0 ; i<wsize; i++) buf[i] = '0'; csock = getpty(&dsock); if(csock == -1) { perror("ptty"); exit(1); } if(fork() == 0) { /* Child, writes on slave. */ close(csock); while(write(dsock, buf, wsize) != -1) ; } else { /* parent reads from controller */ close(dsock); while(read(csock, buf, wsize) != -1) ; } exit(0); } getpty(ip) int *ip; { static char name[] = "/dev/ptyp0"; int i; int res; for(i=0; i<16; i++) { name[9] = i+'0'; res = open(name, 2); if(res != -1) { name[5] = 't'; *ip = open(name, 2); if(*ip != -1) return(res); name[5] = 'p'; close(res); } } return(-1); } Fix: *WARNING* This modification introduces the following bug: * A read from the controller side into an invalid or write-protected * * user buffer (failing with an EFAULT error) may consume data that * * should have been read but was not delivered to the user. * I consider this a minor nit, and am willing to put up with it considering the payoff. First, remove the #ifdef notdef around the q_to_b() function in file sys/tty_subr.c. Then, edit routine ptcread() in file sys/tty_pty.c as follows: 1) add the local definition char ptc_rdbuf[BUFSIZ]; after the other local defs in ptcread() 2) change the loop while (tp->t_outq.c_cc && uio->uio_resid > 0) if (ureadc(getc(&tp->t_outq), uio) < 0) { error = EFAULT; break; } to be while(uio->uio_resid > 0 && error == 0) { int cc = q_to_b(&tp->t_outq, ptc_rdbuf, MIN(uio->uio_resid, BUFSIZ)); if(cc == 0) break; error = uiomove(ptc_rdbuf, cc, UIO_READ, uio); } We have been using this code for 4 months. You may not experience quite as great an improvement as we did, because we also improved the performance of q_to_b(). -- Brian Thomson, CSRG Univ. of Toronto {linus,ihnp4,uw-beaver,floyd,utzoo}!utcsrgv!uthub!thomson