summaryrefslogtreecommitdiffstats
path: root/sys/kern/tty.c
diff options
context:
space:
mode:
authorbde <bde@FreeBSD.org>1998-03-07 15:36:29 +0000
committerbde <bde@FreeBSD.org>1998-03-07 15:36:29 +0000
commitab37e4723bce19187dad7e0b6f58bb0940032588 (patch)
treee9d95fa1b9dd666ce7c0730bf4977e8f3c166395 /sys/kern/tty.c
parent5bf363454e7e3df02636b0ab1023fafd9fb38236 (diff)
downloadFreeBSD-src-ab37e4723bce19187dad7e0b6f58bb0940032588.zip
FreeBSD-src-ab37e4723bce19187dad7e0b6f58bb0940032588.tar.gz
Set the input and output buffer sizes and the input buffer watermarks
dynamically depending on the line speed(s). This should give the old sizes and watermarks until drivers are changed. Display the input watermarks in pstat and sicontrol.
Diffstat (limited to 'sys/kern/tty.c')
-rw-r--r--sys/kern/tty.c110
1 files changed, 71 insertions, 39 deletions
diff --git a/sys/kern/tty.c b/sys/kern/tty.c
index bac398b..64dcf31 100644
--- a/sys/kern/tty.c
+++ b/sys/kern/tty.c
@@ -1,3 +1,5 @@
+static volatile int ttyverbose = 0;
+
/*-
* Copyright (c) 1982, 1986, 1990, 1991, 1993
* The Regents of the University of California. All rights reserved.
@@ -36,7 +38,7 @@
* SUCH DAMAGE.
*
* @(#)tty.c 8.8 (Berkeley) 1/21/94
- * $Id: tty.c,v 1.99 1997/12/06 13:23:52 bde Exp $
+ * $Id: tty.c,v 1.100 1997/12/16 17:40:24 eivind Exp $
*/
/*-
@@ -190,16 +192,8 @@ static u_char const char_type[] = {
#define CLR(t, f) (t) &= ~(f)
#define ISSET(t, f) ((t) & (f))
-/*
- * Input control starts when we would not be able to fit the maximum
- * contents of the ping-pong buffers and finishes when we would be able
- * to fit that much plus 1/8 more.
- */
-#define I_HIGH_WATER (TTYHOG - 2 * 256) /* XXX */
-#define I_LOW_WATER ((TTYHOG - 2 * 256) * 7 / 8) /* XXX */
-
#undef MAX_INPUT /* XXX wrong in <sys/syslimits.h> */
-#define MAX_INPUT TTYHOG
+#define MAX_INPUT TTYHOG /* XXX limit is usually larger for !ICANON */
/*
* Initial open of tty, or (re)entry to standard tty line discipline.
@@ -219,16 +213,7 @@ ttyopen(device, tp)
SET(tp->t_state, TS_CONNECTED);
bzero(&tp->t_winsize, sizeof(tp->t_winsize));
}
-
- /*
- * Initialize or restore a cblock allocation policy suitable for
- * the standard line discipline.
- */
- clist_alloc_cblocks(&tp->t_canq, TTYHOG, 512);
- clist_alloc_cblocks(&tp->t_outq, TTMAXHIWAT + OBUFSIZ + 100,
- TTMAXHIWAT + OBUFSIZ + 100);
- clist_alloc_cblocks(&tp->t_rawq, TTYHOG, TTYHOG);
-
+ ttsetwater(tp);
splx(s);
return (0);
}
@@ -318,7 +303,7 @@ ttyinput(c, tp)
* The 3 is slop for PARMRK.
*/
iflag = tp->t_iflag;
- if (tp->t_rawq.c_cc + tp->t_canq.c_cc > I_HIGH_WATER - 3 &&
+ if (tp->t_rawq.c_cc + tp->t_canq.c_cc > tp->t_ihiwat - 3 &&
(!ISSET(lflag, ICANON) || tp->t_canq.c_cc != 0) &&
(ISSET(tp->t_cflag, CRTS_IFLOW) || ISSET(iflag, IXOFF)) &&
!ISSET(tp->t_state, TS_TBLOCK))
@@ -556,7 +541,7 @@ parmrk:
if (tp->t_rawq.c_cc + tp->t_canq.c_cc >= MAX_INPUT) {
input_overflow:
if (ISSET(iflag, IMAXBEL)) {
- if (tp->t_outq.c_cc < tp->t_hiwat)
+ if (tp->t_outq.c_cc < tp->t_ohiwat)
(void)ttyoutput(CTRL('g'), tp);
}
goto endcase;
@@ -1055,7 +1040,7 @@ ttypoll(tp, events, p)
selrecord(p, &tp->t_rsel);
if (events & (POLLOUT | POLLWRNORM))
- if ((tp->t_outq.c_cc <= tp->t_lowat &&
+ if ((tp->t_outq.c_cc <= tp->t_olowat &&
ISSET(tp->t_state, TS_CONNECTED))
|| ISSET(tp->t_state, TS_ZOMBIE))
revents |= events & (POLLOUT | POLLWRNORM);
@@ -1681,7 +1666,7 @@ out:
*/
s = spltty();
if (ISSET(tp->t_state, TS_TBLOCK) &&
- tp->t_rawq.c_cc + tp->t_canq.c_cc <= I_LOW_WATER)
+ tp->t_rawq.c_cc + tp->t_canq.c_cc <= tp->t_ilowat)
ttyunblock(tp);
splx(s);
@@ -1702,7 +1687,7 @@ ttycheckoutq(tp, wait)
{
int hiwat, s, oldsig;
- hiwat = tp->t_hiwat;
+ hiwat = tp->t_ohiwat;
s = spltty();
oldsig = wait ? curproc->p_siglist : 0;
if (tp->t_outq.c_cc > hiwat + OBUFSIZ + 100)
@@ -1736,7 +1721,7 @@ ttwrite(tp, uio, flag)
int i, hiwat, cnt, error, s;
char obuf[OBUFSIZ];
- hiwat = tp->t_hiwat;
+ hiwat = tp->t_ohiwat;
cnt = uio->uio_resid;
error = 0;
cc = 0;
@@ -2111,7 +2096,7 @@ ttwwakeup(tp)
register struct tty *tp;
{
- if (tp->t_wsel.si_pid != 0 && tp->t_outq.c_cc <= tp->t_lowat)
+ if (tp->t_wsel.si_pid != 0 && tp->t_outq.c_cc <= tp->t_olowat)
selwakeup(&tp->t_wsel);
if (ISSET(tp->t_state, TS_BUSY | TS_SO_OCOMPLETE) ==
TS_SO_OCOMPLETE && tp->t_outq.c_cc == 0) {
@@ -2119,7 +2104,7 @@ ttwwakeup(tp)
wakeup(TSA_OCOMPLETE(tp));
}
if (ISSET(tp->t_state, TS_SO_OLOWAT) &&
- tp->t_outq.c_cc <= tp->t_lowat) {
+ tp->t_outq.c_cc <= tp->t_olowat) {
CLR(tp->t_state, TS_SO_OLOWAT);
wakeup(TSA_OLOWAT(tp));
}
@@ -2142,25 +2127,72 @@ ttspeedtab(speed, table)
}
/*
- * Set tty hi and low water marks.
- *
- * Try to arrange the dynamics so there's about one second
- * from hi to low water.
- *
+ * Set input and output watermarks and buffer sizes. For input, the
+ * high watermark is about one second's worth of input above empty, the
+ * low watermark is slightly below high water, and the buffer size is a
+ * driver-dependent amount above high water. For output, the watermarks
+ * are near the ends of the buffer, with about 1 second's worth of input
+ * between them. All this only applies to the standard line discipline.
*/
void
ttsetwater(tp)
struct tty *tp;
{
- register int cps, x;
+ register int cps, ttmaxhiwat, x;
+ /* Input. */
+ clist_alloc_cblocks(&tp->t_canq, TTYHOG, 512);
+ if (ttyverbose)
+ printf("ttsetwater: can: %d, ", TTYHOG);
+ switch (tp->t_ispeedwat) {
+ case (speed_t)-1:
+ cps = tp->t_ispeed / 10;
+ break;
+ case 0:
+ /*
+ * This case is for old drivers that don't know about
+ * t_ispeedwat. Arrange for them to get the old buffer
+ * sizes and watermarks.
+ */
+ cps = TTYHOG - 2 * 256;
+ tp->t_ififosize = 2 * 256;
+ break;
+ default:
+ cps = tp->t_ispeedwat / 10;
+ break;
+ }
+ tp->t_ihiwat = cps;
+ tp->t_ilowat = 7 * cps / 8;
+ x = cps + tp->t_ififosize;
+ clist_alloc_cblocks(&tp->t_rawq, x, x);
+ if (ttyverbose)
+ printf("raw: %d, ", x);
+
+ /* Output. */
+ switch (tp->t_ospeedwat) {
+ case (speed_t)-1:
+ cps = tp->t_ospeed / 10;
+ ttmaxhiwat = 200000;
+ break;
+ case 0:
+ cps = tp->t_ospeed / 10;
+ ttmaxhiwat = TTMAXHIWAT;
+ break;
+ default:
+ cps = tp->t_ospeedwat / 10;
+ ttmaxhiwat = 200000;
+ break;
+ }
#define CLAMP(x, h, l) ((x) > h ? h : ((x) < l) ? l : (x))
-
- cps = tp->t_ospeed / 10;
- tp->t_lowat = x = CLAMP(cps / 2, TTMAXLOWAT, TTMINLOWAT);
+ tp->t_olowat = x = CLAMP(cps / 2, TTMAXLOWAT, TTMINLOWAT);
x += cps;
- x = CLAMP(x, TTMAXHIWAT, TTMINHIWAT);
- tp->t_hiwat = roundup(x, CBSIZE);
+ x = CLAMP(x, ttmaxhiwat, TTMINHIWAT); /* XXX clamps are too magic */
+ tp->t_ohiwat = roundup(x, CBSIZE); /* XXX for compat */
+ x = imax(tp->t_ohiwat, TTMAXHIWAT); /* XXX for compat/safety */
+ x += OBUFSIZ + 100;
+ clist_alloc_cblocks(&tp->t_outq, x, x);
+ if (ttyverbose)
+ printf("out: %d\n", x);
#undef CLAMP
}
OpenPOWER on IntegriCloud