123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303 |
- /*
- * Mach Operating System
- * Copyright (c) 1992,1991,1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
- /*
- * Author: David B. Golub, Carnegie Mellon University
- * Date: 7/90
- *
- * Circular buffers for TTY
- */
- #include <string.h>
- #include <device/cirbuf.h>
- #include <kern/debug.h>
- #include <kern/kalloc.h>
- /* read at c_cf, write at c_cl */
- /* if c_cf == c_cl, buffer is empty */
- /* if c_cl == c_cf - 1, buffer is full */
- #if DEBUG
- #include <mach/boolean.h>
- boolean_t cb_check_enable = FALSE;
- #define CB_CHECK(cb) if (cb_check_enable) cb_check(cb)
- void
- cb_check(struct cirbuf *cb)
- {
- if (!(cb->c_cf >= cb->c_start && cb->c_cf < cb->c_end))
- panic("cf %x out of range [%x..%x)",
- cb->c_cf, cb->c_start, cb->c_end);
- if (!(cb->c_cl >= cb->c_start && cb->c_cl < cb->c_end))
- panic("cl %x out of range [%x..%x)",
- cb->c_cl, cb->c_start, cb->c_end);
- if (cb->c_cf <= cb->c_cl) {
- if (!(cb->c_cc == cb->c_cl - cb->c_cf))
- panic("cc %x should be %x",
- cb->c_cc,
- cb->c_cl - cb->c_cf);
- }
- else {
- if (!(cb->c_cc == cb->c_end - cb->c_cf
- + cb->c_cl - cb->c_start))
- panic("cc %x should be %x",
- cb->c_cc,
- cb->c_end - cb->c_cf +
- cb->c_cl - cb->c_start);
- }
- }
- #else /* DEBUG */
- #define CB_CHECK(cb)
- #endif /* DEBUG */
- /*
- * Put one character in circular buffer.
- */
- int putc(
- int c,
- struct cirbuf *cb)
- {
- char *ow, *nw;
- ow = cb->c_cl;
- nw = ow+1;
- if (nw == cb->c_end)
- nw = cb->c_start;
- if (nw == cb->c_cf)
- return 1; /* not entered */
- *ow = c;
- cb->c_cl = nw;
- cb->c_cc++;
- CB_CHECK(cb);
- return 0;
- }
- /*
- * Get one character from circular buffer.
- */
- int getc(struct cirbuf *cb)
- {
- unsigned char *nr;
- int c;
- nr = (unsigned char *)cb->c_cf;
- if (nr == (unsigned char *)cb->c_cl) {
- CB_CHECK(cb);
- return -1; /* empty */
- }
- c = *nr;
- nr++;
- if (nr == (unsigned char *)cb->c_end)
- nr = (unsigned char *)cb->c_start;
- cb->c_cf = (char *)nr;
- cb->c_cc--;
- CB_CHECK(cb);
- return c;
- }
- /*
- * Get lots of characters.
- * Return number moved.
- */
- int
- q_to_b( struct cirbuf *cb,
- char *cp,
- int count)
- {
- char *ocp = cp;
- int i;
- while (count != 0) {
- if (cb->c_cl == cb->c_cf)
- break; /* empty */
- if (cb->c_cl < cb->c_cf)
- i = cb->c_end - cb->c_cf;
- else
- i = cb->c_cl - cb->c_cf;
- if (i > count)
- i = count;
- memcpy(cp, cb->c_cf, i);
- cp += i;
- count -= i;
- cb->c_cf += i;
- cb->c_cc -= i;
- if (cb->c_cf == cb->c_end)
- cb->c_cf = cb->c_start;
- CB_CHECK(cb);
- }
- CB_CHECK(cb);
- return cp - ocp;
- }
- /*
- * Add character array to buffer and return number of characters
- * NOT entered.
- */
- int
- b_to_q( char *cp,
- int count,
- struct cirbuf *cb)
- {
- int i;
- char *lim;
- while (count != 0) {
- lim = cb->c_cf - 1;
- if (lim < cb->c_start)
- lim = cb->c_end - 1;
- if (cb->c_cl == lim)
- break;
- if (cb->c_cl < lim)
- i = lim - cb->c_cl;
- else
- i = cb->c_end - cb->c_cl;
- if (i > count)
- i = count;
- memcpy(cb->c_cl, cp, i);
- cp += i;
- count -= i;
- cb->c_cc += i;
- cb->c_cl += i;
- if (cb->c_cl == cb->c_end)
- cb->c_cl = cb->c_start;
- CB_CHECK(cb);
- }
- CB_CHECK(cb);
- return count;
- }
- /*
- * Return number of contiguous characters up to a character
- * that matches the mask.
- */
- int
- ndqb( struct cirbuf *cb,
- int mask)
- {
- char *cp, *lim;
- if (cb->c_cl < cb->c_cf)
- lim = cb->c_end;
- else
- lim = cb->c_cl;
- if (mask == 0)
- return (lim - cb->c_cf);
- cp = cb->c_cf;
- while (cp < lim) {
- if (*cp & mask)
- break;
- cp++;
- }
- return (cp - cb->c_cf);
- }
- /*
- * Flush characters from circular buffer.
- */
- void
- ndflush(struct cirbuf *cb,
- int count)
- {
- int i;
- while (count != 0) {
- if (cb->c_cl == cb->c_cf)
- break; /* empty */
- if (cb->c_cl < cb->c_cf)
- i = cb->c_end - cb->c_cf;
- else
- i = cb->c_cl - cb->c_cf;
- if (i > count)
- i = count;
- count -= i;
- cb->c_cf += i;
- cb->c_cc -= i;
- if (cb->c_cf == cb->c_end)
- cb->c_cf = cb->c_start;
- CB_CHECK(cb);
- }
- CB_CHECK(cb);
- }
- /*
- * Empty a circular buffer.
- */
- void cb_clear(struct cirbuf *cb)
- {
- cb->c_cf = cb->c_start;
- cb->c_cl = cb->c_start;
- cb->c_cc = 0;
- }
- /*
- * Allocate character space for a circular buffer.
- */
- void
- cb_alloc(
- struct cirbuf *cb,
- vm_size_t buf_size)
- {
- char *buf;
- buf = (char *)kalloc(buf_size);
- cb->c_start = buf;
- cb->c_end = buf + buf_size;
- cb->c_cf = buf;
- cb->c_cl = buf;
- cb->c_cc = 0;
- cb->c_hog = buf_size - 1;
- CB_CHECK(cb);
- }
- /*
- * Free character space for a circular buffer.
- */
- void
- cb_free(struct cirbuf *cb)
- {
- vm_size_t size;
- size = cb->c_end - cb->c_start;
- kfree((vm_offset_t)cb->c_start, size);
- }
|