qio: Track Qdropoverflow as a state
authorBarret Rhoden <brho@cs.berkeley.edu>
Thu, 16 Jul 2015 16:28:58 +0000 (12:28 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Fri, 24 Jul 2015 07:05:13 +0000 (03:05 -0400)
Instead of a bool.

kern/include/ns.h
kern/src/ns/qio.c

index 7052970..d102584 100644 (file)
@@ -598,15 +598,15 @@ struct cmdtab {
        int narg;                                       /* expected #args; 0 ==> variadic */
 };
 
-/* queue state bits,  Qmsg, Qcoalesce, and Qkick can be set in qopen */
+/* queue state bits, all can be set in qopen (Qstarve is always set) */
 enum {
-       /* Queue.state */
        Qstarve = (1 << 0),                     /* consumer starved */
        Qmsg = (1 << 1),        /* message stream */
        Qclosed = (1 << 2),     /* queue has been closed/hungup */
        Qflow = (1 << 3),       /* producer flow controlled */
        Qcoalesce = (1 << 4),   /* coallesce packets on read */
        Qkick = (1 << 5),       /* always call the kick routine after qwrite */
+       Qdropoverflow = (1 << 6),       /* writes that would block will be dropped */
 };
 
 #define DEVDOTDOT -1
index 54a776d..0038d82 100644 (file)
@@ -46,7 +46,6 @@ struct queue {
        int limit;                                      /* max bytes in queue */
        int inilim;                             /* initial limit */
        int state;
-       int noblock;                            /* true if writes return immediately when q full */
        int eof;                                        /* number of eofs read by user */
 
        void (*kick) (void *);          /* restart output */
@@ -1161,7 +1160,6 @@ struct queue *qopen(int limit, int msg, void (*kick) (void *), void *arg)
        q->state = msg;
        q->state |= Qstarve;
        q->eof = 0;
-       q->noblock = 0;
 
        return q;
 }
@@ -1544,7 +1542,7 @@ static int qnotfull(void *a)
        return q->len < q->limit || (q->state & Qclosed);
 }
 
-uint32_t noblockcnt;
+uint32_t dropcnt;
 
 /*
  *  add a block to a queue obeying flow control
@@ -1581,10 +1579,10 @@ long qbwrite(struct queue *q, struct block *b)
 
        /* if nonblocking, don't queue over the limit */
        if (q->len >= q->limit) {
-               if (q->noblock) {
+               if (q->state & Qdropoverflow) {
                        spin_unlock_irqsave(&q->lock);
                        freeb(b);
-                       noblockcnt += n;
+                       dropcnt += n;
                        qunlock(&q->wlock);
                        poperror();
                        return n;
@@ -1632,7 +1630,7 @@ long qbwrite(struct queue *q, struct block *b)
         *  queue infinite crud.
         */
        for (;;) {
-               if (q->noblock || qnotfull(q))
+               if ((q->state & Qdropoverflow) || qnotfull(q))
                        break;
 
                spin_lock_irqsave(&q->lock);
@@ -1789,13 +1787,12 @@ void qclose(struct queue *q)
        /* mark it */
        spin_lock_irqsave(&q->lock);
        q->state |= Qclosed;
-       q->state &= ~(Qflow | Qstarve);
+       q->state &= ~(Qflow | Qstarve | Qdropoverflow);
        strncpy(q->err, Ehungup, sizeof(q->err));
        bfirst = q->bfirst;
        q->bfirst = 0;
        q->len = 0;
        q->dlen = 0;
-       q->noblock = 0;
        spin_unlock_irqsave(&q->lock);
 
        /* free queued blocks */
@@ -1889,7 +1886,10 @@ void qsetlimit(struct queue *q, int limit)
  */
 void qdropoverflow(struct queue *q, bool onoff)
 {
-       q->noblock = onoff;
+       if (onoff)
+               q->state |= Qdropoverflow;
+       else
+               q->state &= ~Qdropoverflow;
 }
 
 /*