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

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

unix.superglobalmegacorp.com

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