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

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: 
                     33: #include <device/cirbuf.h>
                     34: #include <kern/kalloc.h>
                     35: 
                     36: 
                     37: 
                     38: /* read at c_cf, write at c_cl */
                     39: /* if c_cf == c_cl, buffer is empty */
                     40: /* if c_cl == c_cf - 1, buffer is full */
                     41: 
                     42: #if    DEBUG
                     43: int cb_check_enable = 0;
                     44: #define        CB_CHECK(cb) if (cb_check_enable) cb_check(cb)
                     45: 
                     46: void
                     47: cb_check(register struct cirbuf *cb)
                     48: {
                     49:        if (!(cb->c_cf >= cb->c_start && cb->c_cf < cb->c_end))
                     50:            panic("cf %x out of range [%x..%x)",
                     51:                cb->c_cf, cb->c_start, cb->c_end);
                     52:        if (!(cb->c_cl >= cb->c_start && cb->c_cl < cb->c_end))
                     53:            panic("cl %x out of range [%x..%x)",
                     54:                cb->c_cl, cb->c_start, cb->c_end);
                     55:        if (cb->c_cf <= cb->c_cl) {
                     56:            if (!(cb->c_cc == cb->c_cl - cb->c_cf))
                     57:                panic("cc %x should be %x",
                     58:                        cb->c_cc,
                     59:                        cb->c_cl - cb->c_cf);
                     60:        }
                     61:        else {
                     62:            if (!(cb->c_cc == cb->c_end - cb->c_cf
                     63:                            + cb->c_cl - cb->c_start))
                     64:                panic("cc %x should be %x",
                     65:                        cb->c_cc,
                     66:                        cb->c_end - cb->c_cf +
                     67:                        cb->c_cl - cb->c_start);
                     68:        }
                     69: }
                     70: #else  /* DEBUG */
                     71: #define        CB_CHECK(cb)
                     72: #endif /* DEBUG */
                     73: 
                     74: /*
                     75:  * Put one character in circular buffer.
                     76:  */
                     77: int putc(
                     78:        int     c,
                     79:        register struct cirbuf *cb)
                     80: {
                     81:        register char *ow, *nw;
                     82: 
                     83:        ow = cb->c_cl;
                     84:        nw = ow+1;
                     85:        if (nw == cb->c_end)
                     86:            nw = cb->c_start;
                     87:        if (nw == cb->c_cf)
                     88:            return 1;           /* not entered */
                     89:        *ow = c;
                     90:        cb->c_cl = nw;
                     91: 
                     92:        cb->c_cc++;
                     93: 
                     94:        CB_CHECK(cb);
                     95: 
                     96:        return 0;
                     97: }
                     98: 
                     99: /*
                    100:  * Get one character from circular buffer.
                    101:  */
                    102: int getc(register struct cirbuf *cb)
                    103: {
                    104:        register unsigned char *nr;
                    105:        register int    c;
                    106: 
                    107:        nr = (unsigned char *)cb->c_cf;
                    108:        if (nr == (unsigned char *)cb->c_cl) {
                    109:            CB_CHECK(cb);
                    110:            return -1;          /* empty */
                    111:        }
                    112:        c = *nr;
                    113:        nr++;
                    114:        if (nr == (unsigned char *)cb->c_end)
                    115:            nr = (unsigned char *)cb->c_start;
                    116:        cb->c_cf = (char *)nr;
                    117: 
                    118:        cb->c_cc--;
                    119: 
                    120:        CB_CHECK(cb);
                    121: 
                    122:        return c;
                    123: }
                    124: 
                    125: /*
                    126:  * Get lots of characters.
                    127:  * Return number moved.
                    128:  */
                    129: int
                    130: q_to_b( register struct cirbuf *cb,
                    131:        register char   *cp,
                    132:        register int    count)
                    133: {
                    134:        char *          ocp = cp;
                    135:        register int    i;
                    136: 
                    137:        while (count != 0) {
                    138:            if (cb->c_cl == cb->c_cf)
                    139:                break;          /* empty */
                    140:            if (cb->c_cl < cb->c_cf)
                    141:                i = cb->c_end - cb->c_cf;
                    142:            else
                    143:                i = cb->c_cl - cb->c_cf;
                    144:            if (i > count)
                    145:                i = count;
                    146:            bcopy(cb->c_cf, cp, i);
                    147:            cp += i;
                    148:            count -= i;
                    149:            cb->c_cf += i;
                    150:            cb->c_cc -= i;
                    151:            if (cb->c_cf == cb->c_end)
                    152:                cb->c_cf = cb->c_start;
                    153: 
                    154:            CB_CHECK(cb);
                    155:        }
                    156:        CB_CHECK(cb);
                    157: 
                    158:        return cp - ocp;
                    159: }
                    160: 
                    161: /*
                    162:  * Add character array to buffer and return number of characters
                    163:  * NOT entered.
                    164:  */
                    165: int
                    166: b_to_q( register char *        cp,
                    167:        int     count,
                    168:        register struct cirbuf *cb)
                    169: {
                    170:        register int    i;
                    171:        register char   *lim;
                    172: 
                    173:        while (count != 0) {
                    174:            lim = cb->c_cf - 1;
                    175:            if (lim < cb->c_start)
                    176:                lim = cb->c_end - 1;
                    177: 
                    178:            if (cb->c_cl == lim)
                    179:                break;
                    180:            if (cb->c_cl < lim)
                    181:                i = lim - cb->c_cl;
                    182:            else
                    183:                i = cb->c_end - cb->c_cl;
                    184: 
                    185:            if (i > count)
                    186:                i = count;
                    187:            bcopy(cp, cb->c_cl, i);
                    188:            cp += i;
                    189:            count -= i;
                    190:            cb->c_cc += i;
                    191:            cb->c_cl += i;
                    192:            if (cb->c_cl == cb->c_end)
                    193:                cb->c_cl = cb->c_start;
                    194: 
                    195:            CB_CHECK(cb);
                    196:        }
                    197:        CB_CHECK(cb);
                    198:        return count;
                    199: }
                    200: 
                    201: /*
                    202:  * Return number of contiguous characters up to a character
                    203:  * that matches the mask.
                    204:  */
                    205: int
                    206: ndqb(  register struct cirbuf *cb,
                    207:        register int    mask)
                    208: {
                    209:        register char *cp, *lim;
                    210: 
                    211:        if (cb->c_cl < cb->c_cf)
                    212:            lim = cb->c_end;
                    213:        else
                    214:            lim = cb->c_cl;
                    215:        if (mask == 0)
                    216:            return (lim - cb->c_cf);
                    217:        cp = cb->c_cf;
                    218:        while (cp < lim) {
                    219:            if (*cp & mask)
                    220:                break;
                    221:            cp++;
                    222:        }
                    223:        return (cp - cb->c_cf);
                    224: }
                    225: 
                    226: /*
                    227:  * Flush characters from circular buffer.
                    228:  */
                    229: void
                    230: ndflush(register struct cirbuf *cb,
                    231:        register int    count)
                    232: {
                    233:        register int    i;
                    234: 
                    235:        while (count != 0) {
                    236:            if (cb->c_cl == cb->c_cf)
                    237:                break;          /* empty */
                    238:            if (cb->c_cl < cb->c_cf)
                    239:                i = cb->c_end - cb->c_cf;
                    240:            else
                    241:                i = cb->c_cl - cb->c_cf;
                    242:            if (i > count)
                    243:                i = count;
                    244:            count -= i;
                    245:            cb->c_cf += i;
                    246:            cb->c_cc -= i;
                    247:            if (cb->c_cf == cb->c_end)
                    248:                cb->c_cf = cb->c_start;
                    249:            CB_CHECK(cb);
                    250:        }
                    251: 
                    252:        CB_CHECK(cb);
                    253: }
                    254: 
                    255: /*
                    256:  * Empty a circular buffer.
                    257:  */
                    258: void cb_clear(struct cirbuf *cb)
                    259: {
                    260:        cb->c_cf = cb->c_start;
                    261:        cb->c_cl = cb->c_start;
                    262:        cb->c_cc = 0;
                    263: }
                    264: 
                    265: /*
                    266:  * Allocate character space for a circular buffer.
                    267:  */
                    268: void
                    269: cb_alloc(
                    270:        register struct cirbuf *cb,
                    271:        int             buf_size)
                    272: {
                    273:        register char *buf;
                    274: 
                    275:        buf = (char *)kalloc(buf_size);
                    276: 
                    277:        cb->c_start = buf;
                    278:        cb->c_end = buf + buf_size;
                    279:        cb->c_cf = buf;
                    280:        cb->c_cl = buf;
                    281:        cb->c_cc = 0;
                    282:        cb->c_hog = buf_size - 1;
                    283: 
                    284:        CB_CHECK(cb);
                    285: }
                    286: 
                    287: /*
                    288:  * Free character space for a circular buffer.
                    289:  */
                    290: void
                    291: cb_free(register struct cirbuf *cb)
                    292: {
                    293:        int             size;
                    294: 
                    295:        size = cb->c_end - cb->c_start;
                    296:        kfree((vm_offset_t)cb->c_start, size);
                    297: }
                    298: 

unix.superglobalmegacorp.com

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