[comp.os.minix] V1.3 posting #35 - major performance improvement to RS232 driver

ast@cs.vu.nl (Andy Tanenbaum) (07/17/88)

I have been hacking on the RS232 stuff to improve the performance.  The
fixes enclosed below make a major difference.  With them, you can run a
plain vanilla PC at 1200 baud, with only very occasionally losing characters.

To avoid confusion later, I suggest that everyone apply these fixes, and we'll
call the result 1.3b.  This is important later, because when I post the final
1.3 diffs, they will be relative to 1.3b (i.e., I will assume you have made
these fixes).

As people start using the RS232 stuff, please post comments, experience, 
performance on various machines etc.

Andy Tanenbaum (ast@cs.vu.nl)

: This is a shar archive.  Extract with sh, not csh.
: This archive ends with exit, so do not worry about trailing junk.
: --------------------------- cut here --------------------------
PATH=/bin:/usr/bin:/usr/ucb
echo Extracting 'clock.cdif'
sed 's/^X//' > 'clock.cdif' << '+ END-OF-FILE ''clock.cdif'
X*** kernel/clock.c	Thu Jul 14 00:00:18 1988
X--- clock.c	Sat Jul 16 23:54:00 1988
X***************
X*** 190,202 ****
X    }
X  
X    accounting();			/* keep track of who is using the cpu */
X-   if (flush_flag) rs_flush();	/* flush accumulated tty input */
X  
X    /* If a user process has been running too long, pick another one. */
X    if (--sched_ticks == 0) {
X  	if (bill_ptr == prev_ptr) sched();	/* process has run too long */
X  	sched_ticks = SCHED_RATE;		/* reset quantum */
X  	prev_ptr = bill_ptr;			/* new previous process */
X  
X  	/* Check if printer is hung up, and if so, restart it. */
X  	if (pr_busy && pcount > 0 && cum_count == prev_ct) pr_char(); 
X--- 190,204 ----
X    }
X  
X    accounting();			/* keep track of who is using the cpu */
X  
X    /* If a user process has been running too long, pick another one. */
X    if (--sched_ticks == 0) {
X  	if (bill_ptr == prev_ptr) sched();	/* process has run too long */
X  	sched_ticks = SCHED_RATE;		/* reset quantum */
X  	prev_ptr = bill_ptr;			/* new previous process */
X+ 
X+ 	/* If characters are accumulating, call the TTY task. */
X+ 	if (flush_flag) rs_flush();	/* flush accumulated tty input */
X  
X  	/* Check if printer is hung up, and if so, restart it. */
X  	if (pr_busy && pcount > 0 && cum_count == prev_ct) pr_char(); 
+ END-OF-FILE clock.cdif
chmod 'u=rw,g=r,o=r' 'clock.cdif'
set `wc -c 'clock.cdif'`
count=$1
case $count in
1281)	:;;
*)	echo 'Bad character count in ''clock.cdif' >&2
		echo 'Count should be 1281' >&2
esac
echo Extracting 'term.cdif'
sed 's/^X//' > 'term.cdif' << '+ END-OF-FILE ''term.cdif'
X*** commands/term.c	Thu Jul 14 14:12:20 1988
X--- term.c	Sat Jul 16 23:54:01 1988
X***************
X*** 24,31 ****
X  #define MODEM "/dev/tty1"	/* special file attached to the modem */
X  #define ESC 033			/* character to hit to leave simulator */
X  #define LIMIT 3			/* how often do you have to hit  ESC to exit*/
X  
X! int modem, pid;				/* file descriptor for modem */
X  char *pat[NCHECKS] = 
X  	{"5", "6", "7", "8", "110", "300", "1200", "2400", "4800", "9600"};
X  
X--- 24,32 ----
X  #define MODEM "/dev/tty1"	/* special file attached to the modem */
X  #define ESC 033			/* character to hit to leave simulator */
X  #define LIMIT 3			/* how often do you have to hit  ESC to exit*/
X+ #define CHUNK 1024		/* how much to read at once */
X  
X! int modem, pid;			/* file descriptor for modem */
X  char *pat[NCHECKS] = 
X  	{"5", "6", "7", "8", "110", "300", "1200", "2400", "4800", "9600"};
X  
X***************
X*** 70,77 ****
X    speed = DEF_SPEED;		/* default line speed */
X    bits = DEF_BITS;		/* default bits/char */
X    for (i = 1; i < argc; i++) {
X! 	if (strcmp(argv[i], "even") == 0) {parity = ODDP; continue;}
X! 	if (strcmp(argv[i], "odd") == 0)  {parity = EVENP; continue;}
X  	v = validity(argv[i]);
X  	if (v == BAD) {
X  		printf("Invalid parameter: %s\n", argv[i]);
X--- 71,78 ----
X    speed = DEF_SPEED;		/* default line speed */
X    bits = DEF_BITS;		/* default bits/char */
X    for (i = 1; i < argc; i++) {
X! 	if (strcmp(argv[i], "even") == 0) {parity = EVENP; continue;}
X! 	if (strcmp(argv[i], "odd") == 0)  {parity = ODDP; continue;}
X  	v = validity(argv[i]);
X  	if (v == BAD) {
X  		printf("Invalid parameter: %s\n", argv[i]);
X***************
X*** 88,94 ****
X  	}
X  	if (nspeeds > 1) error("Too many speeds\n");
X  	if (nbits > 1) error("Too many character sizes\n");
X- 
X    }
X  
X    /* Fetch the modem parameters, save them, and set new ones. */
X--- 89,94 ----
X***************
X*** 130,151 ****
X   * modem are unsigned integers in the range 0 to 255.
X   */
X  
X!   int t, state = 0;
X!   char c;
X  
X    while (1) {
X! 	if (read(in, &c, 1) != 1) {
X  		printf("Can't read from modem\r\n");
X  		quit();
X  	}
X! 	t = c & 0377;			/* note: t is unsigned int 0 - 255 */
X! 	if (t == end) {
X! 		state++;
X! 		if (state == LIMIT) quit();
X! 	} else {
X! 		state = 0;
X  	}
X! 	write(out, &c, 1);
X    }
X  }
X  
X--- 130,155 ----
X   * modem are unsigned integers in the range 0 to 255.
X   */
X  
X!   int t, count, state = 0;
X!   char buf[CHUNK], *p;
X  
X    while (1) {
X! 	if ( (count = read(in, buf, CHUNK)) < 0) {
X  		printf("Can't read from modem\r\n");
X  		quit();
X  	}
X! 
X! 	if (end > 0) {
X! 		for (p = &buf[0]; p < &buf[count]; p++) {
X! 			t = *p & 0377;		/* t is unsigned int 0 - 255 */
X! 			if (t == end) {
X! 				if (++state == LIMIT) quit();
X! 			} else {
X! 				state = 0;
X! 			}
X! 		}
X  	}
X! 	write(out, buf, count);
X    }
X  }
X  
+ END-OF-FILE term.cdif
chmod 'u=rw,g=r,o=r' 'term.cdif'
set `wc -c 'term.cdif'`
count=$1
case $count in
2815)	:;;
*)	echo 'Bad character count in ''term.cdif' >&2
		echo 'Count should be 2815' >&2
esac
echo Extracting 'tty.cdif'
sed 's/^X//' > 'tty.cdif' << '+ END-OF-FILE ''tty.cdif'
X*** kernel/tty.c	Thu Jul 14 00:00:18 1988
X--- tty.c	Sat Jul 16 23:54:55 1988
X***************
X*** 1742,1748 ****
X   * line.  In both cases, start the output.
X   */
X  
X-   char byte;
X    int val;
X    struct tty_struct *tp;
X    struct rs_struct *rs;
X--- 1742,1747 ----
X***************
X*** 1964,1971 ****
X  /*===========================================================================*
X   *				tty_o_done				     *
X   *===========================================================================*/
X! PRIVATE int tty_o_done(tp)
X! register struct tty_struct *tp;	/* pointer to tty_struct */
X  {
X  /* A write request on an RS232 line has completed.  Send FS a message. */
X  
X--- 1963,1969 ----
X  /*===========================================================================*
X   *				tty_o_done				     *
X   *===========================================================================*/
X! PRIVATE int tty_o_done()
X  {
X  /* A write request on an RS232 line has completed.  Send FS a message. */
X  
X***************
X*** 2121,2124 ****
X  }
X  
X  #endif
X- 
X--- 2119,2121 ----
+ END-OF-FILE tty.cdif
chmod 'u=rw,g=r,o=r' 'tty.cdif'
set `wc -c 'tty.cdif'`
count=$1
case $count in
1061)	:;;
*)	echo 'Bad character count in ''tty.cdif' >&2
		echo 'Count should be 1061' >&2
esac
exit 0