From: Matthew Dillon Date: Thu, 4 Oct 2018 21:37:12 +0000 (-0700) Subject: kernel - Refactor tty clist code X-Git-Tag: v5.5.0~115 X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/4725869b060b0e647b6c64480a0ce50f64ff23bb kernel - Refactor tty clist code * Remove all the old cruft, completely rewrite the clist code to use a single linear buffer and a FIFO mechanism. * The linear buffer just uses 16-bit elements in order to record TTY_QUOTE along with the character. * Fixes bug in last commit (lack of global locks around global clist caches) by removing the cache entirely. --- diff --git a/sys/bus/u4b/serial/usb_serial.c b/sys/bus/u4b/serial/usb_serial.c index 2101d7a09c..6ad1d70bc3 100644 --- a/sys/bus/u4b/serial/usb_serial.c +++ b/sys/bus/u4b/serial/usb_serial.c @@ -92,7 +92,6 @@ #include #include #include -#include #include #include @@ -1903,7 +1902,7 @@ ucom_get_data(struct ucom_softc *sc, struct usb_page_cache *pc, } /* copy data directly into USB buffer */ SET(tp->t_state, TS_BUSY); - cnt = q_to_b(&tp->t_outq, res.buffer, len); + cnt = clist_qtob(&tp->t_outq, res.buffer, len); if (cnt == 0) { DPRINTF("ucom_get_data: cnt == 0\n"); CLR(tp->t_state, TS_BUSY); @@ -2026,7 +2025,7 @@ ucom_put_data(struct ucom_softc *sc, struct usb_page_cache *pc, || tp->t_iflag & IXOFF) && !(tp->t_state & TS_TBLOCK)) ttyblock(tp); - lostcc = b_to_q((char *)buf, cnt, &tp->t_rawq); + lostcc = clist_btoq((char *)buf, cnt, &tp->t_rawq); tp->t_rawcc += cnt; if (sc->hotchar) { while (cnt) { diff --git a/sys/dev/misc/syscons/syscons.c b/sys/dev/misc/syscons/syscons.c index 4d1f6e4f8e..4a86319f88 100644 --- a/sys/dev/misc/syscons/syscons.c +++ b/sys/dev/misc/syscons/syscons.c @@ -1778,7 +1778,7 @@ scstart(struct tty *tp) tp->t_state |= TS_BUSY; rbp = &tp->t_outq; while (rbp->c_cc) { - len = q_to_b(rbp, buf, PCBURST); + len = clist_qtob(rbp, buf, PCBURST); sc_puts(scp, buf, len); } tp->t_state &= ~TS_BUSY; diff --git a/sys/dev/serial/sio/sio.c b/sys/dev/serial/sio/sio.c index 30f225b958..d8d79a5025 100644 --- a/sys/dev/serial/sio/sio.c +++ b/sys/dev/serial/sio/sio.c @@ -1701,7 +1701,7 @@ sioinput(struct com_s *com) && !(tp->t_state & TS_TBLOCK)) ttyblock(tp); com->delta_error_counts[CE_TTY_BUF_OVERFLOW] - += b_to_q((char *)buf, incc, &tp->t_rawq); + += clist_btoq((char *)buf, incc, &tp->t_rawq); buf += incc; tk_nin += incc; tk_rawcc += incc; @@ -2556,8 +2556,8 @@ comstart(struct tty *tp) if (!com->obufs[0].l_queued) { com->obufs[0].l_tail - = com->obuf1 + q_to_b(&tp->t_outq, com->obuf1, - sizeof com->obuf1); + = com->obuf1 + clist_qtob(&tp->t_outq, com->obuf1, + sizeof com->obuf1); com->obufs[0].l_next = NULL; com->obufs[0].l_queued = TRUE; com_lock(); @@ -2576,8 +2576,8 @@ comstart(struct tty *tp) } if (tp->t_outq.c_cc != 0 && !com->obufs[1].l_queued) { com->obufs[1].l_tail - = com->obuf2 + q_to_b(&tp->t_outq, com->obuf2, - sizeof com->obuf2); + = com->obuf2 + clist_qtob(&tp->t_outq, com->obuf2, + sizeof com->obuf2); com->obufs[1].l_next = NULL; com->obufs[1].l_queued = TRUE; com_lock(); diff --git a/sys/kern/tty.c b/sys/kern/tty.c index aa11d67474..28ca3746d0 100644 --- a/sys/kern/tty.c +++ b/sys/kern/tty.c @@ -82,7 +82,6 @@ #define TTYDEFCHARS #include /* for ttydefchars, CEOT */ #undef TTYDEFCHARS -#include #include #include #include @@ -693,7 +692,7 @@ input_overflow: } if (TTBREAKC(c, lflag)) { tp->t_rocount = 0; - catq(&tp->t_rawq, &tp->t_canq); + clist_catq(&tp->t_rawq, &tp->t_canq); ttwakeup(tp); } else if (tp->t_rocount++ == 0) tp->t_rocol = tp->t_column; @@ -773,7 +772,7 @@ ttyoutput(int c, struct tty *tp) ISSET(oflag, OXTABS) && !ISSET(tp->t_lflag, EXTPROC)) { c = 8 - (tp->t_column & 7); if (!ISSET(tp->t_lflag, FLUSHO)) { - c -= b_to_q(" ", c, &tp->t_outq); + c -= clist_btoq(" ", c, &tp->t_outq); tk_nout += c; tp->t_outcc += c; } @@ -1093,15 +1092,15 @@ ttioctl(struct tty *tp, u_long cmd, void *data, int flag) * discipline. Now we have to worry about * panicing for a null queue. */ - if (tp->t_canq.c_cbreserved > 0 && - tp->t_rawq.c_cbreserved > 0) { - catq(&tp->t_rawq, &tp->t_canq); + if (tp->t_canq.c_ccmax > 0 && + tp->t_rawq.c_ccmax > 0) { + clist_catq(&tp->t_rawq, &tp->t_canq); /* * XXX the queue limits may be * different, so the old queue * swapping method no longer works. */ - catq(&tp->t_canq, &tp->t_rawq); + clist_catq(&tp->t_canq, &tp->t_rawq); } CLR(tp->t_lflag, PENDIN); } @@ -1655,11 +1654,11 @@ ttypend(struct tty *tp) */ tq = tp->t_rawq; bzero(&tp->t_rawq, sizeof tp->t_rawq); - tp->t_rawq.c_cbmax = tq.c_cbmax; - tp->t_rawq.c_cbreserved = tq.c_cbreserved; + clist_alloc_cblocks(&tp->t_rawq, tq.c_ccmax); while ((c = clist_getc(&tq)) >= 0) ttyinput(c, tp); CLR(tp->t_state, TS_TYPEN); + clist_free_cblocks(&tq); lwkt_reltoken(&tp->t_token); } @@ -1858,7 +1857,7 @@ read: int icc; icc = (int)szmin(uio->uio_resid, IBUFSIZ); - icc = q_to_b(qp, ibuf, icc); + icc = clist_qtob(qp, ibuf, icc); if (icc <= 0) { if (first) goto loop; @@ -2114,7 +2113,7 @@ loop: * requiring special handling by ttyoutput. */ tp->t_rocount = 0; - i = b_to_q(cp, ce, &tp->t_outq); + i = clist_btoq(cp, ce, &tp->t_outq); ce -= i; tp->t_column += ce; cp += ce, cc -= ce, tk_nout += ce; @@ -2179,7 +2178,7 @@ ovhiwat: static void ttyrub(int c, struct tty *tp) { - char *cp; + void *cp; int savecol; int tabc; @@ -2220,11 +2219,13 @@ ttyrub(int c, struct tty *tp) SET(tp->t_state, TS_CNTTB); SET(tp->t_lflag, FLUSHO); tp->t_column = tp->t_rocol; - cp = tp->t_rawq.c_cf; - if (cp) - tabc = *cp; /* XXX FIX NEXTC */ - for (; cp; cp = nextc(&tp->t_rawq, cp, &tabc)) + + cp = clist_nextc(&tp->t_rawq, NULL, &tabc); + while (cp) { ttyecho(tabc, tp); + cp = clist_nextc(&tp->t_rawq, + cp, &tabc); + } CLR(tp->t_lflag, FLUSHO); CLR(tp->t_state, TS_CNTTB); @@ -2288,7 +2289,7 @@ ttyrubo(struct tty *tp, int cnt) static void ttyretype(struct tty *tp) { - char *cp; + void *cp; int c; ASSERT_LWKT_TOKEN_HELD(&tp->t_token); @@ -2303,12 +2304,16 @@ ttyretype(struct tty *tp) * FIX: NEXTC IS BROKEN - DOESN'T CHECK QUOTE * BIT OF FIRST CHAR. */ - for (cp = tp->t_canq.c_cf, c = (cp != NULL ? *cp : 0); - cp != NULL; cp = nextc(&tp->t_canq, cp, &c)) + cp = clist_nextc(&tp->t_canq, NULL, &c); + while (cp) { ttyecho(c, tp); - for (cp = tp->t_rawq.c_cf, c = (cp != NULL ? *cp : 0); - cp != NULL; cp = nextc(&tp->t_rawq, cp, &c)) + cp = clist_nextc(&tp->t_canq, cp, &c); + } + cp = clist_nextc(&tp->t_rawq, NULL, &c); + while (cp) { ttyecho(c, tp); + cp = clist_nextc(&tp->t_rawq, cp, &c); + } CLR(tp->t_state, TS_ERASE); tp->t_rocount = tp->t_rawq.c_cc; @@ -2410,7 +2415,7 @@ ttsetwater(struct tty *tp) lwkt_gettoken(&tp->t_token); /* Input. */ - clist_alloc_cblocks(&tp->t_canq, TTYHOG, 512); + clist_alloc_cblocks(&tp->t_canq, TTYHOG); switch (tp->t_ispeedwat) { case (speed_t)-1: cps = tp->t_ispeed / 10; @@ -2431,7 +2436,7 @@ ttsetwater(struct tty *tp) tp->t_ihiwat = cps; tp->t_ilowat = 7 * cps / 8; x = cps + tp->t_ififosize; - clist_alloc_cblocks(&tp->t_rawq, x, x); + clist_alloc_cblocks(&tp->t_rawq, x); /* Output. */ switch (tp->t_ospeedwat) { @@ -2452,10 +2457,10 @@ ttsetwater(struct tty *tp) tp->t_olowat = x = CLAMP(cps / 2, TTMAXLOWAT, TTMINLOWAT); x += cps; x = CLAMP(x, ttmaxhiwat, TTMINHIWAT); /* XXX clamps are too magic */ - tp->t_ohiwat = roundup(x, CBSIZE); /* XXX for compat */ + /* 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); + clist_alloc_cblocks(&tp->t_outq, x); #undef CLAMP lwkt_reltoken(&tp->t_token); } diff --git a/sys/kern/tty_pty.c b/sys/kern/tty_pty.c index a0378fa2e4..1bcea02bbe 100644 --- a/sys/kern/tty_pty.c +++ b/sys/kern/tty_pty.c @@ -815,8 +815,8 @@ ptcread(struct dev_read_args *ap) if (pti->pt_flags & (PF_PKT|PF_UCNTL)) error = ureadc(0, ap->a_uio); while (ap->a_uio->uio_resid > 0 && error == 0) { - cc = q_to_b(&tp->t_outq, buf, - (int)szmin(ap->a_uio->uio_resid, BUFSIZ)); + cc = clist_qtob(&tp->t_outq, buf, + (int)szmin(ap->a_uio->uio_resid, BUFSIZ)); if (cc <= 0) break; error = uiomove(buf, (size_t)cc, ap->a_uio); @@ -1036,10 +1036,10 @@ again: } } if (cc > 0) { - cc = b_to_q((char *)cp, cc, &tp->t_canq); + cc = clist_btoq((char *)cp, cc, &tp->t_canq); /* * XXX we don't guarantee that the canq size - * is >= TTYHOG, so the above b_to_q() may + * is >= TTYHOG, so the above btoq() may * leave some bytes uncopied. However, space * is guaranteed for the null terminator if * we don't fail here since (TTYHOG - 1) is diff --git a/sys/kern/tty_subr.c b/sys/kern/tty_subr.c index f41e286208..1b73ba6e3d 100644 --- a/sys/kern/tty_subr.c +++ b/sys/kern/tty_subr.c @@ -1,8 +1,10 @@ /* - * (MPSAFE) - * * Copyright (c) 1994, David Greenman * All rights reserved. + * Copyright (c) 2003-2011 The DragonFly Project. All rights reserved. + * + * This code is derived from software contributed to The DragonFly Project + * by Matthew Dillon * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -25,709 +27,276 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD: src/sys/kern/tty_subr.c,v 1.32 1999/08/28 00:46:21 peter Exp $ - */ - -/* - * MPSAFE NOTE: - * Most functions here could use a separate lock to deal with concurrent - * access to the cblocks and cblock_*_list. */ /* * clist support routines * - * NOTE on cblock->c_cf: This pointer may point at the base of a cblock, - * which is &cblock->c_info[0], but will never - * point at the end of a cblock (char *)(cblk + 1) - * - * NOTE on cblock->c_cl: This pointer will never point at the base of - * a block but may point at the end of one. - * - * These routines may be used by more then just ttys, so a critical section - * must be used to access the free list, and for general safety. + * The clist now contains two linear buffers c_quote and c_info, sized + * to c_cbmax. The caller must hold a lock or token specific to the clist + * being manipulated. */ - #include #include #include #include #include -#include #include -static void clist_init (void *); -SYSINIT(clist, SI_SUB_CLIST, SI_ORDER_FIRST, clist_init, NULL); - -static struct cblock *cfreelist = NULL; -int cfreecount = 0; -static int cslushcount; -static int ctotcount; - -#ifndef INITIAL_CBLOCKS -#define INITIAL_CBLOCKS 50 -#endif - -static struct cblock *cblock_alloc (void); -static void cblock_alloc_cblocks (int number); -static void cblock_free (struct cblock *cblockp); -static void cblock_free_cblocks (int number); - -#include "opt_ddb.h" -#ifdef DDB -#include - -DB_SHOW_COMMAND(cbstat, cbstat) -{ - int cbsize = CBSIZE; - - kprintf( - "tot = %d (active = %d, free = %d (reserved = %d, slush = %d))\n", - ctotcount * cbsize, ctotcount * cbsize - cfreecount, cfreecount, - cfreecount - cslushcount * cbsize, cslushcount * cbsize); -} -#endif /* DDB */ - -/* - * Called from init_main.c - */ -/* ARGSUSED*/ -static void -clist_init(void *dummy) -{ - /* - * Allocate an initial base set of cblocks as a 'slush'. - * We allocate non-slush cblocks with each initial ttyopen() and - * deallocate them with each ttyclose(). - * We should adjust the slush allocation. This can't be done in - * the i/o routines because they are sometimes called from - * interrupt handlers when it may be unsafe to call kmalloc(). - */ - cblock_alloc_cblocks(cslushcount = INITIAL_CBLOCKS); - KKASSERT(sizeof(struct cblock) == CBLOCK); -} - /* - * Remove a cblock from the cfreelist queue and return a pointer - * to it. - * - * May not block. - * - * NOTE: Must be called with the related tp->t_token held + * Allocate or reallocate clist buffers. */ -static struct cblock * -cblock_alloc(void) -{ - struct cblock *cblockp; - - cblockp = cfreelist; - if (cblockp == NULL) - panic("clist reservation botch"); - KKASSERT(cblockp->c_head.ch_magic == CLIST_MAGIC_FREE); - cfreelist = cblockp->c_head.ch_next; - cblockp->c_head.ch_next = NULL; - cblockp->c_head.ch_magic = CLIST_MAGIC_USED; - cfreecount -= CBSIZE; - return (cblockp); -} - -/* - * Add a cblock to the cfreelist queue. - * - * May not block, must be called in a critical section - * - * NOTE: Must be called with the related tp->t_token held. - */ -static void -cblock_free(struct cblock *cblockp) +void +clist_alloc_cblocks(struct clist *cl, int ccmax) { - if (isset(cblockp->c_quote, CBQSIZE * NBBY - 1)) - bzero(cblockp->c_quote, sizeof cblockp->c_quote); - KKASSERT(cblockp->c_head.ch_magic == CLIST_MAGIC_USED); - cblockp->c_head.ch_next = cfreelist; - cblockp->c_head.ch_magic = CLIST_MAGIC_FREE; - cfreelist = cblockp; - cfreecount += CBSIZE; -} + short *data; + int count; + int n; -/* - * Allocate some cblocks for the cfreelist queue. - * - * This routine may block, but still must be called in a critical section - * - * NOTE: Must be called with the related tp->t_token held. - */ -static void -cblock_alloc_cblocks(int number) -{ - int i; - struct cblock *cbp; - - for (i = 0; i < number; ++i) { - cbp = kmalloc(sizeof *cbp, M_TTYS, M_NOWAIT); - if (cbp == NULL) { - kprintf("clist_alloc_cblocks: M_NOWAIT " - "kmalloc failed, trying M_WAITOK\n"); - cbp = kmalloc(sizeof *cbp, M_TTYS, M_WAITOK); + if (ccmax == cl->c_ccmax) + return; + if (ccmax == 0) { + clist_free_cblocks(cl); + return; + } + data = kmalloc(ccmax * sizeof(*data), M_TTYS, M_INTWAIT|M_ZERO); + /* NOTE: cl fields may now be different due to blocking */ + + count = cl->c_cc; + if (cl->c_cc) { + if (count > ccmax) + count = ccmax; + n = cl->c_ccmax - cl->c_cchead; + if (n > count) + n = count; + bcopy(cl->c_data + cl->c_cchead, data, n * sizeof(*data)); + if (n < count) { + bcopy(cl->c_data, data + n, + (count - n) * sizeof(*data)); } - KKASSERT(((intptr_t)cbp & CROUND) == 0); - /* - * Freed cblocks have zero quotes and garbage elsewhere. - * Set the may-have-quote bit to force zeroing the quotes. - */ - setbit(cbp->c_quote, CBQSIZE * NBBY - 1); - cbp->c_head.ch_magic = CLIST_MAGIC_USED; - cblock_free(cbp); } - ctotcount += number; + cl->c_cc = count; + cl->c_ccmax = ccmax; + cl->c_cchead = 0; + cl->c_data = data; } /* - * Set the cblock allocation policy for a clist. - * - * NOTE: Must be called with the related tp->t_token held. + * Free the clist's buffer. */ void -clist_alloc_cblocks(struct clist *clistp, int ccmax, int ccreserved) +clist_free_cblocks(struct clist *cl) { - int dcbr; + short *data; - /* - * Allow for wasted space at the head. - */ - if (ccmax != 0) - ccmax += CBSIZE - 1; - if (ccreserved != 0) - ccreserved += CBSIZE - 1; - - clistp->c_cbmax = roundup(ccmax, CBSIZE) / CBSIZE; - dcbr = roundup(ccreserved, CBSIZE) / CBSIZE - clistp->c_cbreserved; - if (dcbr >= 0) { - clistp->c_cbreserved += dcbr; /* atomic w/c_cbmax */ - cblock_alloc_cblocks(dcbr); /* may block */ - } else { - KKASSERT(clistp->c_cbcount <= clistp->c_cbreserved); - if (clistp->c_cbreserved + dcbr < clistp->c_cbcount) - dcbr = clistp->c_cbcount - clistp->c_cbreserved; - clistp->c_cbreserved += dcbr; /* atomic w/c_cbmax */ - cblock_free_cblocks(-dcbr); /* may block */ - } - KKASSERT(clistp->c_cbreserved >= 0); -} - -/* - * Free some cblocks from the cfreelist queue back to the - * system malloc pool. - * - * NOTE: Must be called with the related tp->t_token held. - */ -static void -cblock_free_cblocks(int number) -{ - int i; + data = cl->c_data; - for (i = 0; i < number; ++i) - kfree(cblock_alloc(), M_TTYS); - ctotcount -= number; -} - -/* - * Free the cblocks reserved for a clist. - * - * NOTE: Must be called with the related tp->t_token held. - */ -void -clist_free_cblocks(struct clist *clistp) -{ - int cbreserved; - - if (clistp->c_cbcount != 0) - panic("freeing active clist cblocks"); - cbreserved = clistp->c_cbreserved; - clistp->c_cbmax = 0; - clistp->c_cbreserved = 0; - cblock_free_cblocks(cbreserved); /* may block */ + cl->c_cc = 0; + cl->c_ccmax = 0; + cl->c_cchead = 0; + cl->c_unused01 = 0; + cl->c_data = NULL; + if (data) + kfree(data, M_TTYS); } /* * Get a character from the head of a clist. - * - * NOTE: Must be called with the related tp->t_token held. */ int -clist_getc(struct clist *clistp) +clist_getc(struct clist *cl) { - int chr = -1; - struct cblock *cblockp; - - if (clistp->c_cc) { - KKASSERT(((intptr_t)clistp->c_cf & CROUND) != 0); - cblockp = (struct cblock *)((intptr_t)clistp->c_cf & ~CROUND); - chr = (u_char)*clistp->c_cf; - - /* - * If this char is quoted, set the flag. - */ - if (isset(cblockp->c_quote, - clistp->c_cf - (char *)cblockp->c_info)) { - chr |= TTY_QUOTE; - } + short c; + int i; - /* - * Advance to next character. - */ - clistp->c_cf++; - clistp->c_cc--; - /* - * If we have advanced the 'first' character pointer - * past the end of this cblock, advance to the next one. - * If there are no more characters, set the first and - * last pointers to NULL. In either case, free the - * current cblock. - */ - KKASSERT(clistp->c_cf <= (char *)(cblockp + 1)); - if ((clistp->c_cf == (char *)(cblockp + 1)) || - (clistp->c_cc == 0)) { - if (clistp->c_cc > 0) { - clistp->c_cf = cblockp->c_head.ch_next->c_info; - } else { - clistp->c_cf = clistp->c_cl = NULL; - } - cblock_free(cblockp); - if (--clistp->c_cbcount >= clistp->c_cbreserved) - ++cslushcount; - } - } - return (chr); + if (cl->c_cc == 0) + return -1; + i = cl->c_cchead; + c = cl->c_data[i]; + if (++i == cl->c_ccmax) + i = 0; + cl->c_cchead = i; + --cl->c_cc; + return ((int)c); } /* - * Copy 'amount' of chars, beginning at head of clist 'clistp' to - * destination linear buffer 'dest'. Return number of characters - * actually copied. - * - * Caller must hold related tp->t_token + * Copy data from the clist to the destination linear buffer. + * Return the number of characters actually copied. */ int -q_to_b(struct clist *clistp, char *dest, int amount) +clist_qtob(struct clist *cl, char *dest, int n) { - struct cblock *cblockp; - struct cblock *cblockn; - char *dest_orig = dest; - int numc; - - while (clistp && amount && (clistp->c_cc > 0)) { - KKASSERT(((intptr_t)clistp->c_cf & CROUND) != 0); - cblockp = (struct cblock *)((intptr_t)clistp->c_cf & ~CROUND); - cblockn = cblockp + 1; /* pointer arithmetic! */ - numc = min(amount, (char *)cblockn - clistp->c_cf); - numc = min(numc, clistp->c_cc); - bcopy(clistp->c_cf, dest, numc); - amount -= numc; - clistp->c_cf += numc; - clistp->c_cc -= numc; - dest += numc; - /* - * If this cblock has been emptied, advance to the next - * one. If there are no more characters, set the first - * and last pointer to NULL. In either case, free the - * current cblock. - */ - KKASSERT(clistp->c_cf <= (char *)cblockn); - if ((clistp->c_cf == (char *)cblockn) || (clistp->c_cc == 0)) { - if (clistp->c_cc > 0) { - KKASSERT(cblockp->c_head.ch_next != NULL); - clistp->c_cf = cblockp->c_head.ch_next->c_info; - } else { - clistp->c_cf = clistp->c_cl = NULL; - } - cblock_free(cblockp); - if (--clistp->c_cbcount >= clistp->c_cbreserved) - ++cslushcount; - } + int count; + int i; + short c; + + if (n > cl->c_cc) + n = cl->c_cc; + count = n; + i = cl->c_cchead; + + while (n) { + c = cl->c_data[i]; + if (++i == cl->c_ccmax) + i = 0; + *dest++ = (char)c; + --n; } - return (dest - dest_orig); + cl->c_cchead = i; + cl->c_cc -= count; + + return count; } /* - * Flush 'amount' of chars, beginning at head of clist 'clistp'. - * - * Caller must hold related tp->t_token + * Flush characters from the head of the clist, deleting them. */ void -ndflush(struct clist *clistp, int amount) +ndflush(struct clist *cl, int n) { - struct cblock *cblockp; - struct cblock *cblockn; - int numc; - - while (amount && (clistp->c_cc > 0)) { - KKASSERT(((intptr_t)clistp->c_cf & CROUND) != 0); - cblockp = (struct cblock *)((intptr_t)clistp->c_cf & ~CROUND); - cblockn = cblockp + 1; /* pointer arithmetic! */ - numc = min(amount, (char *)cblockn - clistp->c_cf); - numc = min(numc, clistp->c_cc); - amount -= numc; - clistp->c_cf += numc; - clistp->c_cc -= numc; - /* - * If this cblock has been emptied, advance to the next - * one. If there are no more characters, set the first - * and last pointer to NULL. In either case, free the - * current cblock. - */ - KKASSERT(clistp->c_cf <= (char *)cblockn); - if (clistp->c_cf == (char *)cblockn || clistp->c_cc == 0) { - if (clistp->c_cc > 0) { - KKASSERT(cblockp->c_head.ch_next != NULL); - clistp->c_cf = cblockp->c_head.ch_next->c_info; - } else { - clistp->c_cf = clistp->c_cl = NULL; - } - cblock_free(cblockp); - if (--clistp->c_cbcount >= clistp->c_cbreserved) - ++cslushcount; - } - } + int i; + + if (n > cl->c_cc) + n = cl->c_cc; + i = cl->c_cchead + n; + if (i >= cl->c_ccmax) + i -= cl->c_ccmax; + cl->c_cchead = i; + cl->c_cc -= n; } /* - * Add a character to the end of a clist. Return -1 is no - * more clists, or 0 for success. - * - * Caller must hold related tp->t_token + * Append a character to the clist, return 0 on success, -1 if + * there is no room. The character can be quoted by setting TTY_QUOTE. */ int -clist_putc(int chr, struct clist *clistp) +clist_putc(int c, struct clist *cl) { - struct cblock *cblockp; - - /* - * Note: this section may point c_cl at the base of a cblock. This - * is a temporary violation of the requirements for c_cl, we - * increment it before returning. - */ - if (clistp->c_cl == NULL) { - if (clistp->c_cbreserved < 1) { - return (-1); /* nothing done */ - } - cblockp = cblock_alloc(); - clistp->c_cbcount = 1; - clistp->c_cf = clistp->c_cl = cblockp->c_info; - clistp->c_cc = 0; - } else { - cblockp = (struct cblock *)((intptr_t)clistp->c_cl & ~CROUND); - if (((intptr_t)clistp->c_cl & CROUND) == 0) { - struct cblock *prev = (cblockp - 1); - - if (clistp->c_cbcount >= clistp->c_cbreserved) { - if (clistp->c_cbcount >= clistp->c_cbmax - || cslushcount <= 0) { - return (-1); - } - --cslushcount; - } - cblockp = cblock_alloc(); - clistp->c_cbcount++; - prev->c_head.ch_next = cblockp; - clistp->c_cl = cblockp->c_info; - } - } - - /* - * If this character is quoted, set the quote bit, if not, clear it. - */ - if (chr & TTY_QUOTE) { - setbit(cblockp->c_quote, clistp->c_cl - (char *)cblockp->c_info); - /* - * Use one of the spare quote bits to record that something - * may be quoted. - */ - setbit(cblockp->c_quote, CBQSIZE * NBBY - 1); - } else { - clrbit(cblockp->c_quote, clistp->c_cl - (char *)cblockp->c_info); - } + int i; - *clistp->c_cl++ = chr; - clistp->c_cc++; + if (cl->c_cc == cl->c_ccmax) + return -1; + i = cl->c_cchead + cl->c_cc; + if (i >= cl->c_ccmax) + i -= cl->c_ccmax; + cl->c_data[i] = (short)c & (TTY_QUOTE | TTY_CHARMASK); + ++cl->c_cc; - return (0); + return 0; } /* - * Copy data from linear buffer to clist chain. Return the - * number of characters not copied. - * - * Caller must hold related tp->t_token + * Copy data from linear buffer to clist chain. Return the + * number of characters not copied. The data will be flagged + * as not being quoted. */ int -b_to_q(char *src, int amount, struct clist *clistp) +clist_btoq(char *src, int n, struct clist *cl) { - struct cblock *cblockp; - char *firstbyte, *lastbyte; - u_char startmask, endmask; - int startbit, endbit, num_between, numc; - - /* - * Avoid allocating an initial cblock and then not using it. - * c_cc == 0 must imply c_cbount == 0. - */ - if (amount <= 0) - return (amount); - - /* - * Note: this section may point c_cl at the base of a cblock. This - * is a temporary violation of the requirements for c_cl. Since - * amount is non-zero we will not return with it in that state. - */ - if (clistp->c_cl == NULL) { - if (clistp->c_cbreserved < 1) { - kprintf("b_to_q to a clist with no " - "reserved cblocks.\n"); - return (amount); /* nothing done */ - } - cblockp = cblock_alloc(); - clistp->c_cbcount = 1; - clistp->c_cf = clistp->c_cl = cblockp->c_info; - clistp->c_cc = 0; - } else { - /* - * c_cl may legally point past the end of the block, which - * falls through to the 'get another cblock' code below. - */ - cblockp = (struct cblock *)((intptr_t)clistp->c_cl & ~CROUND); + int i; + int count; + int remain; + + count = cl->c_ccmax - cl->c_cc; /* space available */ + if (count > n) + count = n; /* count = bytes to copy */ + remain = n - count; /* remain = bytes not copied */ + + i = cl->c_cchead + cl->c_cc; /* clist write index */ + if (i >= cl->c_ccmax) + i -= cl->c_ccmax; + + while (count) { + cl->c_data[i] = (short)(uint8_t)*src; + if (++i == cl->c_ccmax) + i = 0; + ++src; + --count; } + cl->c_cc += n - remain; /* bytes actually copied */ - while (amount) { - /* - * Get another cblock if needed. - */ - if (((intptr_t)clistp->c_cl & CROUND) == 0) { - struct cblock *prev = cblockp - 1; - - if (clistp->c_cbcount >= clistp->c_cbreserved) { - if (clistp->c_cbcount >= clistp->c_cbmax - || cslushcount <= 0) { - return (amount); - } - --cslushcount; - } - cblockp = cblock_alloc(); - clistp->c_cbcount++; - prev->c_head.ch_next = cblockp; - clistp->c_cl = cblockp->c_info; - } - - /* - * Copy a chunk of the linear buffer up to the end - * of this cblock. - */ - numc = min(amount, (char *)(cblockp + 1) - clistp->c_cl); - bcopy(src, clistp->c_cl, numc); - - /* - * Clear quote bits if they aren't known to be clear. - * The following could probably be made into a separate - * "bitzero()" routine, but why bother? - */ - if (isset(cblockp->c_quote, CBQSIZE * NBBY - 1)) { - startbit = clistp->c_cl - (char *)cblockp->c_info; - endbit = startbit + numc - 1; - - firstbyte = (u_char *)cblockp->c_quote + (startbit / NBBY); - lastbyte = (u_char *)cblockp->c_quote + (endbit / NBBY); - - /* - * Calculate mask of bits to preserve in first and - * last bytes. - */ - startmask = NBBY - (startbit % NBBY); - startmask = 0xff >> startmask; - endmask = (endbit % NBBY); - endmask = 0xff << (endmask + 1); - - if (firstbyte != lastbyte) { - *firstbyte &= startmask; - *lastbyte &= endmask; - - num_between = lastbyte - firstbyte - 1; - if (num_between) - bzero(firstbyte + 1, num_between); - } else { - *firstbyte &= (startmask | endmask); - } - } - - /* - * ...and update pointer for the next chunk. - */ - src += numc; - clistp->c_cl += numc; - clistp->c_cc += numc; - amount -= numc; - /* - * If we go through the loop again, it's always - * for data in the next cblock, so by adding one (cblock), - * (which makes the pointer 1 beyond the end of this - * cblock) we prepare for the assignment of 'prev' - * above. - */ - ++cblockp; - } - return (amount); + return remain; /* return bytes not copied */ } /* - * Get the next character in the clist. Store it at dst. Don't - * advance any clist pointers, but return a pointer to the next - * character position. + * Get the next character in the clist relative to cp. If cp is NULL + * returns the first character in the clist. The character is stored in + * *dst. No clist pointers are advanced or adjusted. * - * Caller must hold related tp->t_token + * The returned pointer can be used as an iterator but should not be + * directly dereferenced. */ -char * -nextc(struct clist *clistp, char *cp, int *dst) +void * +clist_nextc(struct clist *cl, void *cp, int *dst) { - struct cblock *cblockp; + int i; + + if (cp == NULL) { + if (cl->c_cc == 0) { + *dst = -1; + return NULL; + } + cp = &cl->c_data[cl->c_cchead]; + *dst = (uint16_t)*(short *)cp; /* can be quoted */ + return cp; + } /* - * See if the next character is beyond the end of - * the clist. + * Use i to calculate the next logical index to determine if + * there are any characters remaining. */ - ++cp; - if (clistp->c_cc && (cp != clistp->c_cl)) { - /* - * If the next character is beyond the end of this - * cblock, advance to the next cblock. - */ - if (((intptr_t)cp & CROUND) == 0) - cp = ((struct cblock *)cp - 1)->c_head.ch_next->c_info; - cblockp = (struct cblock *)((intptr_t)cp & ~CROUND); - - /* - * Get the character. Set the quote flag if this character - * is quoted. - */ - *dst = (u_char)*cp | - (isset(cblockp->c_quote, cp - (char *)cblockp->c_info) ? - TTY_QUOTE : 0); - - return (cp); + i = (short *)cp - cl->c_data; + if (i < cl->c_cchead) + i += cl->c_ccmax - cl->c_cchead; + else + i -= cl->c_cchead; + if (i + 1 == cl->c_cc) { /* no more chars */ + *dst = 0; + return NULL; } - return (NULL); + + /* + * We can just use cp to iterate the next actual buffer + * position. + */ + cp = (short *)cp + 1; /* next char (use pointer) */ + if (cp == &cl->c_data[cl->c_ccmax]) + cp = &cl->c_data[0]; + *dst = (uint16_t)*(short *)cp; + + return cp; } /* - * "Unput" a character from a clist. - * - * Caller must hold related tp->t_token + * "Unput" a character from a clist, returning it. */ int -clist_unputc(struct clist *clistp) +clist_unputc(struct clist *cl) { - struct cblock *cblockp = NULL, *cbp = NULL; - int chr = -1; - - if (clistp->c_cc) { - /* - * note that clistp->c_cl will never point at the base - * of a cblock (cblock->c_info) (see assert this later on), - * but it may point past the end of one. We temporarily - * violate this in the decrement below but then we fix it up. - */ - --clistp->c_cc; - --clistp->c_cl; - - chr = (u_char)*clistp->c_cl; - - cblockp = (struct cblock *)((intptr_t)clistp->c_cl & ~CROUND); - - /* - * Set quote flag if this character was quoted. - */ - if (isset(cblockp->c_quote, (u_char *)clistp->c_cl - cblockp->c_info)) - chr |= TTY_QUOTE; - - /* - * If all of the characters have been unput in this - * cblock, then find the previous one and free this - * one. - * - * if c_cc is 0 clistp->c_cl may end up pointing at - * cblockp->c_info, which is illegal, but the case will be - * taken care of near the end of the routine. Otherwise - * there *MUST* be another cblock, find it. - */ - KKASSERT(clistp->c_cl >= (char *)cblockp->c_info); - if (clistp->c_cc && (clistp->c_cl == (char *)cblockp->c_info)) { - cbp = (struct cblock *)((intptr_t)clistp->c_cf & - ~CROUND); - - while (cbp->c_head.ch_next != cblockp) - cbp = cbp->c_head.ch_next; - cbp->c_head.ch_next = NULL; - - /* - * When the previous cblock is at the end, the 'last' - * pointer always points (invalidly) one past. - */ - clistp->c_cl = (char *)(cbp + 1); - cblock_free(cblockp); - if (--clistp->c_cbcount >= clistp->c_cbreserved) - ++cslushcount; - } - } + int c; + int i; - /* - * If there are no more characters on the list, then - * free the last cblock. It should not be possible for c->cl - * to be pointing past the end of a block due to our decrement - * of it way above. - */ - if (clistp->c_cc == 0 && clistp->c_cl) { - KKASSERT(((intptr_t)clistp->c_cl & CROUND) != 0); - cblockp = (struct cblock *)((intptr_t)clistp->c_cl & ~CROUND); - cblock_free(cblockp); - if (--clistp->c_cbcount >= clistp->c_cbreserved) - ++cslushcount; - clistp->c_cf = clistp->c_cl = NULL; - } - return (chr); + if (cl->c_cc == 0) + return -1; + --cl->c_cc; + i = cl->c_cchead + cl->c_cc; + if (i >= cl->c_ccmax) + i -= cl->c_ccmax; + c = (int)(uint16_t)cl->c_data[i]; + + return c; } /* * Move characters in source clist to destination clist, - * preserving quote bits. + * preserving quote bits. Non-critical path. */ void -catq(struct clist *src_clistp, struct clist *dest_clistp) +clist_catq(struct clist *cls, struct clist *cld) { - int chr; + int c; - /* - * If the destination clist is empty (has no cblocks atttached), - * and there are no possible complications with the resource counters, - * then we simply assign the current clist to the destination. - */ - if (!dest_clistp->c_cf - && src_clistp->c_cbcount <= src_clistp->c_cbmax - && src_clistp->c_cbcount <= dest_clistp->c_cbmax) { - dest_clistp->c_cf = src_clistp->c_cf; - dest_clistp->c_cl = src_clistp->c_cl; - src_clistp->c_cf = src_clistp->c_cl = NULL; - - dest_clistp->c_cc = src_clistp->c_cc; - src_clistp->c_cc = 0; - dest_clistp->c_cbcount = src_clistp->c_cbcount; - src_clistp->c_cbcount = 0; - - return; - } - - /* - * XXX This should probably be optimized to more than one - * character at a time. - */ - while ((chr = clist_getc(src_clistp)) != -1) - clist_putc(chr, dest_clistp); + while ((c = clist_getc(cls)) != -1) + clist_putc(c, cld); } diff --git a/sys/net/sl/if_sl.c b/sys/net/sl/if_sl.c index 98a045928c..1b07952820 100644 --- a/sys/net/sl/if_sl.c +++ b/sys/net/sl/if_sl.c @@ -75,7 +75,6 @@ #include #include #include -#include #include #include #include @@ -155,7 +154,7 @@ TUNABLE_INT("net.sliffopts", &sliffopts); #define SLMTU 552 /* default MTU */ #endif #define SLTMAX 1500 /* maximum MTU */ -#define SLIP_HIWAT roundup(50,CBSIZE) +#define SLIP_HIWAT 50 #define CLISTRESERVE 1024 /* Can't let clists get too low */ /* @@ -283,11 +282,10 @@ slopen(cdev_t dev, struct tty *tp) * be enough. Reserving cblocks probably makes * the CLISTRESERVE check unnecessary and wasteful. */ - clist_alloc_cblocks(&tp->t_canq, 0, 0); + clist_alloc_cblocks(&tp->t_canq, 0); clist_alloc_cblocks(&tp->t_outq, - SLIP_HIWAT + 2 * sc->sc_if.if_mtu + 1, SLIP_HIWAT + 2 * sc->sc_if.if_mtu + 1); - clist_alloc_cblocks(&tp->t_rawq, 0, 0); + clist_alloc_cblocks(&tp->t_rawq, 0); if_up(&sc->sc_if); lwkt_reltoken(&tty_token); @@ -384,8 +382,8 @@ sltioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct ucred *cred) sc->sc_flags |= (nc->sc_flags & SC_STATIC); tp->t_slsc = sc = nc; clist_alloc_cblocks(&tp->t_outq, - SLIP_HIWAT + 2 * sc->sc_if.if_mtu + 1, - SLIP_HIWAT + 2 * sc->sc_if.if_mtu + 1); + SLIP_HIWAT + + 2 * sc->sc_if.if_mtu + 1); sl_compress_init(&sc->sc_comp, -1); goto slfound; } @@ -631,21 +629,8 @@ slstart(struct tty *tp) bpf_reltoken(); } - /* - * If system is getting low on clists, just flush our - * output queue (if the stuff was important, it'll get - * retransmitted). Note that SLTMAX is used instead of - * the current if_mtu setting because connections that - * have already been established still use the original - * (possibly larger) mss. - */ - if (cfreecount < CLISTRESERVE + SLTMAX) { - m_freem(m); - IFNET_STAT_INC(&sc->sc_if, collisions, 1); - continue; - } - sc->sc_flags &= ~SC_OUTWAIT; + /* * The extra FRAME_END will start up a new packet, and thus * will flush any accumulated garbage. We do this whenever @@ -681,11 +666,12 @@ slstart(struct tty *tp) * Put n characters at once * into the tty output queue. */ - if (b_to_q((char *)bp, cp - bp, - &tp->t_outq)) + if (clist_btoq((char *)bp, cp - bp, + &tp->t_outq)) { break; + } IFNET_STAT_INC(&sc->sc_if, obytes, - cp - bp); + cp - bp); } /* * If there are characters left in the mbuf, @@ -1015,7 +1001,6 @@ slioctl(struct ifnet *ifp, u_long cmd, caddr_t data, struct ucred *cr) tp = sl_softc[ifp->if_dunit].sc_ttyp; if (tp != NULL) clist_alloc_cblocks(&tp->t_outq, - SLIP_HIWAT + 2 * ifp->if_mtu + 1, SLIP_HIWAT + 2 * ifp->if_mtu + 1); } break; diff --git a/sys/netgraph/tty/ng_tty.c b/sys/netgraph/tty/ng_tty.c index cc4e5cf26f..1320fad96c 100644 --- a/sys/netgraph/tty/ng_tty.c +++ b/sys/netgraph/tty/ng_tty.c @@ -240,10 +240,9 @@ ngt_open(cdev_t dev, struct tty *tp) * I'm not sure what is appropriate. */ ttyflush(tp, FREAD | FWRITE); - clist_alloc_cblocks(&tp->t_canq, 0, 0); - clist_alloc_cblocks(&tp->t_rawq, 0, 0); - clist_alloc_cblocks(&tp->t_outq, - MLEN + NGT_HIWATER, MLEN + NGT_HIWATER); + clist_alloc_cblocks(&tp->t_canq, 0); + clist_alloc_cblocks(&tp->t_rawq, 0); + clist_alloc_cblocks(&tp->t_outq, MLEN + NGT_HIWATER); done: /* Done */ @@ -426,8 +425,8 @@ ngt_start(struct tty *tp) while (m) { int sent; - sent = m->m_len - - b_to_q(mtod(m, u_char *), m->m_len, &tp->t_outq); + sent = m->m_len - clist_btoq(mtod(m, u_char *), + m->m_len, &tp->t_outq); m->m_data += sent; m->m_len -= sent; if (m->m_len > 0) diff --git a/sys/netgraph7/bluetooth/drivers/h4/ng_h4.c b/sys/netgraph7/bluetooth/drivers/h4/ng_h4.c index f2f62d3689..44c0ae9784 100644 --- a/sys/netgraph7/bluetooth/drivers/h4/ng_h4.c +++ b/sys/netgraph7/bluetooth/drivers/h4/ng_h4.c @@ -221,10 +221,9 @@ ng_h4_open(struct cdev *dev, struct tty *tp) */ ttyflush(tp, FREAD | FWRITE); - clist_alloc_cblocks(&tp->t_canq, 0, 0); - clist_alloc_cblocks(&tp->t_rawq, 0, 0); - clist_alloc_cblocks(&tp->t_outq, - MLEN + NG_H4_HIWATER, MLEN + NG_H4_HIWATER); + clist_alloc_cblocks(&tp->t_canq, 0); + clist_alloc_cblocks(&tp->t_rawq, 0); + clist_alloc_cblocks(&tp->t_outq, MLEN + NG_H4_HIWATER); NG_H4_UNLOCK(sc); @@ -602,8 +601,8 @@ ng_h4_start(struct tty *tp) /* Send as much of it as possible */ while (m != NULL) { - size = m->m_len - b_to_q(mtod(m, u_char *), - m->m_len, &tp->t_outq); + size = m->m_len - clist_btoq(mtod(m, u_char *), + m->m_len, &tp->t_outq); NG_H4_LOCK(sc); NG_H4_STAT_BYTES_SENT(sc->stat, size); diff --git a/sys/netgraph7/tty/ng_tty.c b/sys/netgraph7/tty/ng_tty.c index 41944face4..7e671f0647 100644 --- a/sys/netgraph7/tty/ng_tty.c +++ b/sys/netgraph7/tty/ng_tty.c @@ -229,10 +229,9 @@ ngt_open(struct cdev *dev, struct tty *tp) * I'm not sure what is appropriate. */ ttyflush(tp, FREAD | FWRITE); - clist_alloc_cblocks(&tp->t_canq, 0, 0); - clist_alloc_cblocks(&tp->t_rawq, 0, 0); - clist_alloc_cblocks(&tp->t_outq, - MLEN + NGT_HIWATER, MLEN + NGT_HIWATER); + clist_alloc_cblocks(&tp->t_canq, 0); + clist_alloc_cblocks(&tp->t_rawq, 0); + clist_alloc_cblocks(&tp->t_outq, MLEN + NGT_HIWATER); lwkt_reltoken(&tp->t_token); return (error); @@ -428,8 +427,8 @@ ngt_start(struct tty *tp) while (m != NULL) { int sent; - sent = m->m_len - - b_to_q(mtod(m, u_char *), m->m_len, &tp->t_outq); + sent = m->m_len - clist_btoq(mtod(m, u_char *), + m->m_len, &tp->t_outq); m->m_data += sent; m->m_len -= sent; if (m->m_len > 0) diff --git a/sys/platform/vkernel64/platform/console.c b/sys/platform/vkernel64/platform/console.c index 81893deec0..183a59c912 100644 --- a/sys/platform/vkernel64/platform/console.c +++ b/sys/platform/vkernel64/platform/console.c @@ -187,7 +187,7 @@ vcons_tty_start(struct tty *tp) return; } tp->t_state |= TS_BUSY; - while ((n = q_to_b(&tp->t_outq, buf, sizeof(buf))) > 0) { + while ((n = clist_qtob(&tp->t_outq, buf, sizeof(buf))) > 0) { /* * Dummy up ttyv1, etc. */ diff --git a/sys/sys/clist.h b/sys/sys/clist.h deleted file mode 100644 index 7187cb71a2..0000000000 --- a/sys/sys/clist.h +++ /dev/null @@ -1,66 +0,0 @@ -/*- - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)clist.h 8.1 (Berkeley) 6/4/93 - * $FreeBSD: src/sys/sys/clist.h,v 1.10 1999/12/29 04:24:38 peter Exp $ - * $DragonFly: src/sys/sys/clist.h,v 1.5 2006/05/20 02:42:13 dillon Exp $ - */ - -#ifndef _SYS_CLIST_H_ -#define _SYS_CLIST_H_ - -#ifndef _SYS_TYPES_H_ -#include -#endif - -#define CBLOCK 128 /* Clist block size, must be a power of 2. */ -#define CBQSIZE (CBLOCK/NBBY) /* Quote bytes/cblock - can do better. */ - /* Data chars/clist. */ -#define CBSIZE (CBLOCK - sizeof(struct cblockhead) - CBQSIZE) -#define CROUND (CBLOCK - 1) /* Clist rounding. */ - -struct cblockhead { - struct cblock *ch_next; - int ch_magic; -}; - -#define CLIST_MAGIC_FREE 0x434c0102 -#define CLIST_MAGIC_USED 0x434c8182 - -struct cblock { - struct cblockhead c_head; /* header */ - unsigned char c_quote[CBQSIZE]; /* quoted characters */ - unsigned char c_info[CBSIZE]; /* characters */ -}; - -#ifdef _KERNEL -extern struct cblock *cfree; -extern int cfreecount; -#endif - -#endif diff --git a/sys/sys/tty.h b/sys/sys/tty.h index 46194348dc..4829ace9d8 100644 --- a/sys/sys/tty.h +++ b/sys/sys/tty.h @@ -55,11 +55,10 @@ */ struct clist { int c_cc; /* Number of characters in the clist. */ - int c_cbcount; /* Number of cblocks. */ - int c_cbmax; /* Max # cblocks allowed for this clist. */ - int c_cbreserved; /* # cblocks reserved for this clist. */ - char *c_cf; /* Pointer to the first cblock. */ - char *c_cl; /* Pointer to the last cblock. */ + int c_ccmax; /* Max # chars for this clist. */ + int c_cchead; /* First char */ + int c_unused01; + short *c_data; /* linear data buffer (no longer chained) */ }; #if defined(_KERNEL) || defined(_KERNEL_STRUCTURES) @@ -138,16 +137,16 @@ struct tty { * and from clists. The buffers are on the stack so their sizes must be * fairly small. */ -#define IBUFSIZ 384 /* Should be >= max value of MIN. */ -#define OBUFSIZ 100 +#define IBUFSIZ 384 /* Should be >= max value of MIN. */ +#define OBUFSIZ 100 #ifndef TTYHOG -#define TTYHOG 1024 +#define TTYHOG 1024 #endif #ifdef _KERNEL -#define TTMAXHIWAT roundup(2048, CBSIZE) -#define TTMINHIWAT roundup(100, CBSIZE) +#define TTMAXHIWAT 2048 +#define TTMINHIWAT 100 #define TTMAXLOWAT 256 #define TTMINLOWAT 32 #endif @@ -212,8 +211,8 @@ struct speedtab { #define DMGET 3 /* Flags on a character passed to ttyinput. */ -#define TTY_CHARMASK 0x000000ff /* Character mask */ -#define TTY_QUOTE 0x00000100 /* Character quoted */ +#define TTY_CHARMASK 0x00ff /* Character mask */ +#define TTY_QUOTE 0x0100 /* Character quoted */ #define TTY_ERRORMASK 0xff000000 /* Error mask */ #define TTY_FE 0x01000000 /* Framing error */ #define TTY_PE 0x02000000 /* Parity error */ @@ -230,11 +229,11 @@ struct speedtab { /* Unique sleep addresses. */ #define TSA_CARR_ON(tp) ((void *)&(tp)->t_rawq) -#define TSA_HUP_OR_INPUT(tp) ((void *)&(tp)->t_rawq.c_cf) -#define TSA_OCOMPLETE(tp) ((void *)&(tp)->t_outq.c_cl) +#define TSA_HUP_OR_INPUT(tp) ((void *)&(tp)->t_rawq.c_cchead) +#define TSA_OCOMPLETE(tp) ((void *)&(tp)->t_outq.c_ccmax) #define TSA_OLOWAT(tp) ((void *)&(tp)->t_outq) -#define TSA_PTC_READ(tp) ((void *)&(tp)->t_outq.c_cf) -#define TSA_PTC_WRITE(tp) ((void *)&(tp)->t_rawq.c_cl) +#define TSA_PTC_READ(tp) ((void *)&(tp)->t_outq.c_cchead) +#define TSA_PTC_WRITE(tp) ((void *)&(tp)->t_rawq.c_ccmax) #define TSA_PTS_READ(tp) ((void *)&(tp)->t_canq) #ifdef _KERNEL @@ -247,17 +246,17 @@ MALLOC_DECLARE(M_TTYS); extern struct tty *constty; /* Temporary virtual console. */ -int b_to_q (char *cp, int cc, struct clist *q); -void catq (struct clist *from, struct clist *to); -void clist_alloc_cblocks (struct clist *q, int ccmax, int ccres); +int clist_btoq (char *cp, int cc, struct clist *q); +void clist_catq (struct clist *from, struct clist *to); +void clist_alloc_cblocks (struct clist *q, int ccmax); void clist_free_cblocks (struct clist *q); int clist_getc (struct clist *q); int clist_unputc (struct clist *q); void ndflush (struct clist *q, int cc); -char *nextc (struct clist *q, char *cp, int *c); +void *clist_nextc (struct clist *q, void *cp, int *c); void nottystop (struct tty *tp, int rw); int clist_putc (int c, struct clist *q); -int q_to_b (struct clist *q, char *cp, int cc); +int clist_qtob (struct clist *q, char *cp, int cc); void termioschars (struct termios *t); int tputchar (int c, struct tty *tp); int ttcompat (struct tty *tp, u_long com, caddr_t data, int flag);