|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.