diff options
author | dg <dg@FreeBSD.org> | 1994-03-20 20:05:55 +0000 |
---|---|---|
committer | dg <dg@FreeBSD.org> | 1994-03-20 20:05:55 +0000 |
commit | ec62ad7189053f170eb9cd90c786a33e1db0494b (patch) | |
tree | e99ae7b787453a122f3e1691f9667e2a1c5733f4 | |
parent | 3c46360cf3926f7a433c57004882789f4c9e58e6 (diff) | |
download | FreeBSD-src-ec62ad7189053f170eb9cd90c786a33e1db0494b.zip FreeBSD-src-ec62ad7189053f170eb9cd90c786a33e1db0494b.tar.gz |
Two fixes from John Dyson to fix hangs and panics when using ctrl-T:
1) tty.c: gather all the info about the processes before calling ttyprintf
(which may block).
2) syscons.c: handle asynchronous output properly (data structures may
be corrupted otherwise).
-rw-r--r-- | sys/dev/syscons/syscons.c | 59 | ||||
-rw-r--r-- | sys/i386/isa/syscons.c | 59 | ||||
-rw-r--r-- | sys/isa/syscons.c | 59 |
3 files changed, 138 insertions, 39 deletions
diff --git a/sys/dev/syscons/syscons.c b/sys/dev/syscons/syscons.c index 565e843..8868795 100644 --- a/sys/dev/syscons/syscons.c +++ b/sys/dev/syscons/syscons.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from:@(#)syscons.c 1.3 940129 - * $Id: syscons.c,v 1.37 1994/03/06 20:56:26 guido Exp $ + * $Id: syscons.c,v 1.38 1994/03/08 15:17:41 davidg Exp $ * */ @@ -163,6 +163,10 @@ static default_attr kernel_default = { (FG_BLACK | BG_LIGHTGREY) << 8 }; +#define CONSOLE_BUFFER_SIZE 1024 +int console_buffer_count; +char console_buffer[CONSOLE_BUFFER_SIZE]; + static scr_stat console[NCONS]; static scr_stat *cur_console = &console[0]; static scr_stat *new_scp, *old_scp; @@ -1054,13 +1058,14 @@ void pcstart(struct tty *tp) #else /* __FreeBSD__ & __386BSD__ */ - int c, s; + int c, s, len, i; scr_stat *scp = get_scr_stat(tp->t_dev); + u_char buf[PCBURST]; if (scp->status & SLKED) return; s = spltty(); - if (!(tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))) + if (!(tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))) { for (;;) { if (RB_LEN(tp->t_out) <= tp->t_lowat) { if (tp->t_state & TS_ASLEEP) { @@ -1078,13 +1083,29 @@ void pcstart(struct tty *tp) break; if (scp->status & SLKED) break; - c = getc(tp->t_out); + len = 0; + while( len < PCBURST) { + buf[len++] = getc(tp->t_out); + if( RB_LEN(tp->t_out) == 0) + break; + } tp->t_state |= TS_BUSY; splx(s); - ansi_put(scp, c); + for(i=0;i<len;i++) + ansi_put(scp, buf[i]); s = spltty(); tp->t_state &= ~TS_BUSY; } + tp->t_state |= TS_BUSY; + if( in_putc == 0) { + int i; + for(i=0;i<console_buffer_count;i++) { + scput(console_buffer[i]); + } + console_buffer_count = 0; + } + tp->t_state &= ~TS_BUSY; + } splx(s); #endif } @@ -1444,7 +1465,7 @@ static void move_crsr(scr_stat *scp, int x, int y) scp->crtat = scp->crt_base + scp->ypos * scp->xsize + scp->xpos; } - +#if 0 static void move_up(u_short *s, u_short *d, u_int len) { s += len; @@ -1452,13 +1473,18 @@ static void move_up(u_short *s, u_short *d, u_int len) while (len-- > 0) *--d = *--s; } +#endif +#if 0 static void move_down(u_short *s, u_short *d, u_int len) { while (len-- > 0) *d++ = *s++; } +#endif +#define move_down(s,d,len) bcopyw(s,d,len/2) +#define move_up(s,d,len) bcopyw(s,d,len/2) static void scan_esc(scr_stat *scp, u_char c) @@ -2031,13 +2057,20 @@ static void scput(u_char c) if (crtat == 0) scinit(); - save = scp->term; - scp->term = kernel_console; - current_default = &kernel_default; - ansi_put(scp, c); - kernel_console = scp->term; - current_default = &user_default; - scp->term = save; + if( in_putc == 0) { + ++in_putc; + save = scp->term; + scp->term = kernel_console; + current_default = &kernel_default; + ansi_put(scp, c); + kernel_console = scp->term; + current_default = &user_default; + scp->term = save; + --in_putc; + } else { + if( console_buffer_count < CONSOLE_BUFFER_SIZE) + console_buffer[console_buffer_count++] = c; + } } diff --git a/sys/i386/isa/syscons.c b/sys/i386/isa/syscons.c index 565e843..8868795 100644 --- a/sys/i386/isa/syscons.c +++ b/sys/i386/isa/syscons.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from:@(#)syscons.c 1.3 940129 - * $Id: syscons.c,v 1.37 1994/03/06 20:56:26 guido Exp $ + * $Id: syscons.c,v 1.38 1994/03/08 15:17:41 davidg Exp $ * */ @@ -163,6 +163,10 @@ static default_attr kernel_default = { (FG_BLACK | BG_LIGHTGREY) << 8 }; +#define CONSOLE_BUFFER_SIZE 1024 +int console_buffer_count; +char console_buffer[CONSOLE_BUFFER_SIZE]; + static scr_stat console[NCONS]; static scr_stat *cur_console = &console[0]; static scr_stat *new_scp, *old_scp; @@ -1054,13 +1058,14 @@ void pcstart(struct tty *tp) #else /* __FreeBSD__ & __386BSD__ */ - int c, s; + int c, s, len, i; scr_stat *scp = get_scr_stat(tp->t_dev); + u_char buf[PCBURST]; if (scp->status & SLKED) return; s = spltty(); - if (!(tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))) + if (!(tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))) { for (;;) { if (RB_LEN(tp->t_out) <= tp->t_lowat) { if (tp->t_state & TS_ASLEEP) { @@ -1078,13 +1083,29 @@ void pcstart(struct tty *tp) break; if (scp->status & SLKED) break; - c = getc(tp->t_out); + len = 0; + while( len < PCBURST) { + buf[len++] = getc(tp->t_out); + if( RB_LEN(tp->t_out) == 0) + break; + } tp->t_state |= TS_BUSY; splx(s); - ansi_put(scp, c); + for(i=0;i<len;i++) + ansi_put(scp, buf[i]); s = spltty(); tp->t_state &= ~TS_BUSY; } + tp->t_state |= TS_BUSY; + if( in_putc == 0) { + int i; + for(i=0;i<console_buffer_count;i++) { + scput(console_buffer[i]); + } + console_buffer_count = 0; + } + tp->t_state &= ~TS_BUSY; + } splx(s); #endif } @@ -1444,7 +1465,7 @@ static void move_crsr(scr_stat *scp, int x, int y) scp->crtat = scp->crt_base + scp->ypos * scp->xsize + scp->xpos; } - +#if 0 static void move_up(u_short *s, u_short *d, u_int len) { s += len; @@ -1452,13 +1473,18 @@ static void move_up(u_short *s, u_short *d, u_int len) while (len-- > 0) *--d = *--s; } +#endif +#if 0 static void move_down(u_short *s, u_short *d, u_int len) { while (len-- > 0) *d++ = *s++; } +#endif +#define move_down(s,d,len) bcopyw(s,d,len/2) +#define move_up(s,d,len) bcopyw(s,d,len/2) static void scan_esc(scr_stat *scp, u_char c) @@ -2031,13 +2057,20 @@ static void scput(u_char c) if (crtat == 0) scinit(); - save = scp->term; - scp->term = kernel_console; - current_default = &kernel_default; - ansi_put(scp, c); - kernel_console = scp->term; - current_default = &user_default; - scp->term = save; + if( in_putc == 0) { + ++in_putc; + save = scp->term; + scp->term = kernel_console; + current_default = &kernel_default; + ansi_put(scp, c); + kernel_console = scp->term; + current_default = &user_default; + scp->term = save; + --in_putc; + } else { + if( console_buffer_count < CONSOLE_BUFFER_SIZE) + console_buffer[console_buffer_count++] = c; + } } diff --git a/sys/isa/syscons.c b/sys/isa/syscons.c index 565e843..8868795 100644 --- a/sys/isa/syscons.c +++ b/sys/isa/syscons.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from:@(#)syscons.c 1.3 940129 - * $Id: syscons.c,v 1.37 1994/03/06 20:56:26 guido Exp $ + * $Id: syscons.c,v 1.38 1994/03/08 15:17:41 davidg Exp $ * */ @@ -163,6 +163,10 @@ static default_attr kernel_default = { (FG_BLACK | BG_LIGHTGREY) << 8 }; +#define CONSOLE_BUFFER_SIZE 1024 +int console_buffer_count; +char console_buffer[CONSOLE_BUFFER_SIZE]; + static scr_stat console[NCONS]; static scr_stat *cur_console = &console[0]; static scr_stat *new_scp, *old_scp; @@ -1054,13 +1058,14 @@ void pcstart(struct tty *tp) #else /* __FreeBSD__ & __386BSD__ */ - int c, s; + int c, s, len, i; scr_stat *scp = get_scr_stat(tp->t_dev); + u_char buf[PCBURST]; if (scp->status & SLKED) return; s = spltty(); - if (!(tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))) + if (!(tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))) { for (;;) { if (RB_LEN(tp->t_out) <= tp->t_lowat) { if (tp->t_state & TS_ASLEEP) { @@ -1078,13 +1083,29 @@ void pcstart(struct tty *tp) break; if (scp->status & SLKED) break; - c = getc(tp->t_out); + len = 0; + while( len < PCBURST) { + buf[len++] = getc(tp->t_out); + if( RB_LEN(tp->t_out) == 0) + break; + } tp->t_state |= TS_BUSY; splx(s); - ansi_put(scp, c); + for(i=0;i<len;i++) + ansi_put(scp, buf[i]); s = spltty(); tp->t_state &= ~TS_BUSY; } + tp->t_state |= TS_BUSY; + if( in_putc == 0) { + int i; + for(i=0;i<console_buffer_count;i++) { + scput(console_buffer[i]); + } + console_buffer_count = 0; + } + tp->t_state &= ~TS_BUSY; + } splx(s); #endif } @@ -1444,7 +1465,7 @@ static void move_crsr(scr_stat *scp, int x, int y) scp->crtat = scp->crt_base + scp->ypos * scp->xsize + scp->xpos; } - +#if 0 static void move_up(u_short *s, u_short *d, u_int len) { s += len; @@ -1452,13 +1473,18 @@ static void move_up(u_short *s, u_short *d, u_int len) while (len-- > 0) *--d = *--s; } +#endif +#if 0 static void move_down(u_short *s, u_short *d, u_int len) { while (len-- > 0) *d++ = *s++; } +#endif +#define move_down(s,d,len) bcopyw(s,d,len/2) +#define move_up(s,d,len) bcopyw(s,d,len/2) static void scan_esc(scr_stat *scp, u_char c) @@ -2031,13 +2057,20 @@ static void scput(u_char c) if (crtat == 0) scinit(); - save = scp->term; - scp->term = kernel_console; - current_default = &kernel_default; - ansi_put(scp, c); - kernel_console = scp->term; - current_default = &user_default; - scp->term = save; + if( in_putc == 0) { + ++in_putc; + save = scp->term; + scp->term = kernel_console; + current_default = &kernel_default; + ansi_put(scp, c); + kernel_console = scp->term; + current_default = &user_default; + scp->term = save; + --in_putc; + } else { + if( console_buffer_count < CONSOLE_BUFFER_SIZE) + console_buffer[console_buffer_count++] = c; + } } |