kernel - Refactor tty clist code
authorMatthew Dillon <dillon@apollo.backplane.com>
Thu, 4 Oct 2018 21:37:12 +0000 (14:37 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Thu, 4 Oct 2018 22:29:49 +0000 (15:29 -0700)
* 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.

13 files changed:
sys/bus/u4b/serial/usb_serial.c
sys/dev/misc/syscons/syscons.c
sys/dev/serial/sio/sio.c
sys/kern/tty.c
sys/kern/tty_pty.c
sys/kern/tty_subr.c
sys/net/sl/if_sl.c
sys/netgraph/tty/ng_tty.c
sys/netgraph7/bluetooth/drivers/h4/ng_h4.c
sys/netgraph7/tty/ng_tty.c
sys/platform/vkernel64/platform/console.c
sys/sys/clist.h [deleted file]
sys/sys/tty.h

index 2101d7a..6ad1d70 100644 (file)
@@ -92,7 +92,6 @@
 #include <sys/serial.h>
 #include <sys/thread2.h>
 #include <sys/conf.h>
-#include <sys/clist.h>
 
 #include <bus/u4b/usb.h>
 #include <bus/u4b/usbdi.h>
@@ -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) {
index 4d1f6e4..4a86319 100644 (file)
@@ -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;
index 30f225b..d8d79a5 100644 (file)
@@ -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();
index aa11d67..28ca374 100644 (file)
@@ -82,7 +82,6 @@
 #define        TTYDEFCHARS
 #include <sys/ttydefaults.h>   /* for ttydefchars, CEOT */
 #undef TTYDEFCHARS
-#include <sys/clist.h>
 #include <sys/fcntl.h>
 #include <sys/conf.h>
 #include <sys/dkstat.h>
@@ -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);
 }
index a0378fa..1bcea02 100644 (file)
@@ -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
index f41e286..1b73ba6 100644 (file)
@@ -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 <dillon@backplane.com>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * 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 <sys/param.h>
 #include <sys/kernel.h>
 #include <sys/systm.h>
 #include <sys/malloc.h>
 #include <sys/tty.h>
-#include <sys/clist.h>
 #include <sys/thread2.h>
 
-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 <ddb/ddb.h>
-
-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);
 }
index 98a0459..1b07952 100644 (file)
@@ -75,7 +75,6 @@
 #include <sys/fcntl.h>
 #include <sys/signalvar.h>
 #include <sys/tty.h>
-#include <sys/clist.h>
 #include <sys/kernel.h>
 #include <sys/sysctl.h>
 #include <sys/conf.h>
@@ -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;
index cc4e5cf..1320fad 100644 (file)
@@ -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)
index f2f62d3..44c0ae9 100644 (file)
@@ -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);
index 41944fa..7e671f0 100644 (file)
@@ -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)
index 81893de..183a59c 100644 (file)
@@ -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 (file)
index 7187cb7..0000000
+++ /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 <sys/types.h>
-#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
index 4619434..4829ace 100644 (file)
  */
 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);