Annotation of Gnu-Mach/device/cirbuf.c, revision 1.1.1.2

1.1       root        1: /* 
                      2:  * Mach Operating System
                      3:  * Copyright (c) 1992,1991,1990 Carnegie Mellon University
                      4:  * All Rights Reserved.
                      5:  * 
                      6:  * Permission to use, copy, modify and distribute this software and its
                      7:  * documentation is hereby granted, provided that both the copyright
                      8:  * notice and this permission notice appear in all copies of the
                      9:  * software, derivative works or modified versions, and any portions
                     10:  * thereof, and that both notices appear in supporting documentation.
                     11:  * 
                     12:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     13:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
                     14:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                     15:  * 
                     16:  * Carnegie Mellon requests users of this software to return to
                     17:  * 
                     18:  *  Software Distribution Coordinator  or  [email protected]
                     19:  *  School of Computer Science
                     20:  *  Carnegie Mellon University
                     21:  *  Pittsburgh PA 15213-3890
                     22:  * 
                     23:  * any improvements or extensions that they make and grant Carnegie Mellon
                     24:  * the rights to redistribute these changes.
                     25:  */
                     26: /*
                     27:  *     Author: David B. Golub, Carnegie Mellon University
                     28:  *     Date:   7/90
                     29:  *
                     30:  *     Circular buffers for TTY
                     31:  */
                     32: 
1.1.1.2 ! root       33: #include <string.h>
1.1       root       34: #include <device/cirbuf.h>
1.1.1.2 ! root       35: #include <kern/debug.h>
1.1       root       36: #include <kern/kalloc.h>
                     37: 
                     38: 
                     39: 
                     40: /* read at c_cf, write at c_cl */
                     41: /* if c_cf == c_cl, buffer is empty */
                     42: /* if c_cl == c_cf - 1, buffer is full */
                     43: 
                     44: #if    DEBUG
                     45: int cb_check_enable = 0;
                     46: #define        CB_CHECK(cb) if (cb_check_enable) cb_check(cb)
                     47: 
                     48: void
1.1.1.2 ! root       49: cb_check(struct cirbuf *cb)
1.1       root       50: {
                     51:        if (!(cb->c_cf >= cb->c_start && cb->c_cf < cb->c_end))
                     52:            panic("cf %x out of range [%x..%x)",
                     53:                cb->c_cf, cb->c_start, cb->c_end);
                     54:        if (!(cb->c_cl >= cb->c_start && cb->c_cl < cb->c_end))
                     55:            panic("cl %x out of range [%x..%x)",
                     56:                cb->c_cl, cb->c_start, cb->c_end);
                     57:        if (cb->c_cf <= cb->c_cl) {
                     58:            if (!(cb->c_cc == cb->c_cl - cb->c_cf))
                     59:                panic("cc %x should be %x",
                     60:                        cb->c_cc,
                     61:                        cb->c_cl - cb->c_cf);
                     62:        }
                     63:        else {
                     64:            if (!(cb->c_cc == cb->c_end - cb->c_cf
                     65:                            + cb->c_cl - cb->c_start))
                     66:                panic("cc %x should be %x",
                     67:                        cb->c_cc,
                     68:                        cb->c_end - cb->c_cf +
                     69:                        cb->c_cl - cb->c_start);
                     70:        }
                     71: }
                     72: #else  /* DEBUG */
                     73: #define        CB_CHECK(cb)
                     74: #endif /* DEBUG */
                     75: 
                     76: /*
                     77:  * Put one character in circular buffer.
                     78:  */
                     79: int putc(
                     80:        int     c,
1.1.1.2 ! root       81:        struct cirbuf *cb)
1.1       root       82: {
1.1.1.2 ! root       83:        char *ow, *nw;
1.1       root       84: 
                     85:        ow = cb->c_cl;
                     86:        nw = ow+1;
                     87:        if (nw == cb->c_end)
                     88:            nw = cb->c_start;
                     89:        if (nw == cb->c_cf)
                     90:            return 1;           /* not entered */
                     91:        *ow = c;
                     92:        cb->c_cl = nw;
                     93: 
                     94:        cb->c_cc++;
                     95: 
                     96:        CB_CHECK(cb);
                     97: 
                     98:        return 0;
                     99: }
                    100: 
                    101: /*
                    102:  * Get one character from circular buffer.
                    103:  */
1.1.1.2 ! root      104: int getc(struct cirbuf *cb)
1.1       root      105: {
1.1.1.2 ! root      106:        unsigned char *nr;
        !           107:        int     c;
1.1       root      108: 
                    109:        nr = (unsigned char *)cb->c_cf;
                    110:        if (nr == (unsigned char *)cb->c_cl) {
                    111:            CB_CHECK(cb);
                    112:            return -1;          /* empty */
                    113:        }
                    114:        c = *nr;
                    115:        nr++;
                    116:        if (nr == (unsigned char *)cb->c_end)
                    117:            nr = (unsigned char *)cb->c_start;
                    118:        cb->c_cf = (char *)nr;
                    119: 
                    120:        cb->c_cc--;
                    121: 
                    122:        CB_CHECK(cb);
                    123: 
                    124:        return c;
                    125: }
                    126: 
                    127: /*
                    128:  * Get lots of characters.
                    129:  * Return number moved.
                    130:  */
                    131: int
1.1.1.2 ! root      132: q_to_b( struct cirbuf *cb,
        !           133:        char    *cp,
        !           134:        int     count)
1.1       root      135: {
1.1.1.2 ! root      136:        char            *ocp = cp;
        !           137:        int             i;
1.1       root      138: 
                    139:        while (count != 0) {
                    140:            if (cb->c_cl == cb->c_cf)
                    141:                break;          /* empty */
                    142:            if (cb->c_cl < cb->c_cf)
                    143:                i = cb->c_end - cb->c_cf;
                    144:            else
                    145:                i = cb->c_cl - cb->c_cf;
                    146:            if (i > count)
                    147:                i = count;
1.1.1.2 ! root      148:            memcpy(cp, cb->c_cf, i);
1.1       root      149:            cp += i;
                    150:            count -= i;
                    151:            cb->c_cf += i;
                    152:            cb->c_cc -= i;
                    153:            if (cb->c_cf == cb->c_end)
                    154:                cb->c_cf = cb->c_start;
                    155: 
                    156:            CB_CHECK(cb);
                    157:        }
                    158:        CB_CHECK(cb);
                    159: 
                    160:        return cp - ocp;
                    161: }
                    162: 
                    163: /*
                    164:  * Add character array to buffer and return number of characters
                    165:  * NOT entered.
                    166:  */
                    167: int
1.1.1.2 ! root      168: b_to_q( char   *cp,
1.1       root      169:        int     count,
1.1.1.2 ! root      170:        struct cirbuf *cb)
1.1       root      171: {
1.1.1.2 ! root      172:        int     i;
        !           173:        char    *lim;
1.1       root      174: 
                    175:        while (count != 0) {
                    176:            lim = cb->c_cf - 1;
                    177:            if (lim < cb->c_start)
                    178:                lim = cb->c_end - 1;
                    179: 
                    180:            if (cb->c_cl == lim)
                    181:                break;
                    182:            if (cb->c_cl < lim)
                    183:                i = lim - cb->c_cl;
                    184:            else
                    185:                i = cb->c_end - cb->c_cl;
                    186: 
                    187:            if (i > count)
                    188:                i = count;
1.1.1.2 ! root      189:            memcpy(cb->c_cl, cp, i);
1.1       root      190:            cp += i;
                    191:            count -= i;
                    192:            cb->c_cc += i;
                    193:            cb->c_cl += i;
                    194:            if (cb->c_cl == cb->c_end)
                    195:                cb->c_cl = cb->c_start;
                    196: 
                    197:            CB_CHECK(cb);
                    198:        }
                    199:        CB_CHECK(cb);
                    200:        return count;
                    201: }
                    202: 
                    203: /*
                    204:  * Return number of contiguous characters up to a character
                    205:  * that matches the mask.
                    206:  */
                    207: int
1.1.1.2 ! root      208: ndqb(  struct cirbuf *cb,
        !           209:        int     mask)
1.1       root      210: {
1.1.1.2 ! root      211:        char *cp, *lim;
1.1       root      212: 
                    213:        if (cb->c_cl < cb->c_cf)
                    214:            lim = cb->c_end;
                    215:        else
                    216:            lim = cb->c_cl;
                    217:        if (mask == 0)
                    218:            return (lim - cb->c_cf);
                    219:        cp = cb->c_cf;
                    220:        while (cp < lim) {
                    221:            if (*cp & mask)
                    222:                break;
                    223:            cp++;
                    224:        }
                    225:        return (cp - cb->c_cf);
                    226: }
                    227: 
                    228: /*
                    229:  * Flush characters from circular buffer.
                    230:  */
                    231: void
1.1.1.2 ! root      232: ndflush(struct cirbuf *cb,
        !           233:        int     count)
1.1       root      234: {
1.1.1.2 ! root      235:        int     i;
1.1       root      236: 
                    237:        while (count != 0) {
                    238:            if (cb->c_cl == cb->c_cf)
                    239:                break;          /* empty */
                    240:            if (cb->c_cl < cb->c_cf)
                    241:                i = cb->c_end - cb->c_cf;
                    242:            else
                    243:                i = cb->c_cl - cb->c_cf;
                    244:            if (i > count)
                    245:                i = count;
                    246:            count -= i;
                    247:            cb->c_cf += i;
                    248:            cb->c_cc -= i;
                    249:            if (cb->c_cf == cb->c_end)
                    250:                cb->c_cf = cb->c_start;
                    251:            CB_CHECK(cb);
                    252:        }
                    253: 
                    254:        CB_CHECK(cb);
                    255: }
                    256: 
                    257: /*
                    258:  * Empty a circular buffer.
                    259:  */
                    260: void cb_clear(struct cirbuf *cb)
                    261: {
                    262:        cb->c_cf = cb->c_start;
                    263:        cb->c_cl = cb->c_start;
                    264:        cb->c_cc = 0;
                    265: }
                    266: 
                    267: /*
                    268:  * Allocate character space for a circular buffer.
                    269:  */
                    270: void
                    271: cb_alloc(
1.1.1.2 ! root      272:        struct cirbuf *cb,
1.1       root      273:        int             buf_size)
                    274: {
1.1.1.2 ! root      275:        char *buf;
1.1       root      276: 
                    277:        buf = (char *)kalloc(buf_size);
                    278: 
                    279:        cb->c_start = buf;
                    280:        cb->c_end = buf + buf_size;
                    281:        cb->c_cf = buf;
                    282:        cb->c_cl = buf;
                    283:        cb->c_cc = 0;
                    284:        cb->c_hog = buf_size - 1;
                    285: 
                    286:        CB_CHECK(cb);
                    287: }
                    288: 
                    289: /*
                    290:  * Free character space for a circular buffer.
                    291:  */
                    292: void
1.1.1.2 ! root      293: cb_free(struct cirbuf *cb)
1.1       root      294: {
                    295:        int             size;
                    296: 
                    297:        size = cb->c_end - cb->c_start;
                    298:        kfree((vm_offset_t)cb->c_start, size);
                    299: }
                    300: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.