Annotation of 43BSDReno/usr.bin/telnet/ring.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1988 Regents of the University of California.
        !             3:  * All rights reserved.
        !             4:  *
        !             5:  * Redistribution and use in source and binary forms are permitted provided
        !             6:  * that: (1) source distributions retain this entire copyright notice and
        !             7:  * comment, and (2) distributions including binaries display the following
        !             8:  * acknowledgement:  ``This product includes software developed by the
        !             9:  * University of California, Berkeley and its contributors'' in the
        !            10:  * documentation or other materials provided with the distribution and in
        !            11:  * all advertising materials mentioning features or use of this software.
        !            12:  * Neither the name of the University nor the names of its contributors may
        !            13:  * be used to endorse or promote products derived from this software without
        !            14:  * specific prior written permission.
        !            15:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
        !            16:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
        !            17:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
        !            18:  */
        !            19: 
        !            20: #ifndef lint
        !            21: static char sccsid[] = "@(#)ring.c     1.13 (Berkeley) 6/28/90";
        !            22: #endif /* not lint */
        !            23: 
        !            24: /*
        !            25:  * This defines a structure for a ring buffer.
        !            26:  *
        !            27:  * The circular buffer has two parts:
        !            28:  *(((
        !            29:  *     full:   [consume, supply)
        !            30:  *     empty:  [supply, consume)
        !            31:  *]]]
        !            32:  *
        !            33:  */
        !            34: 
        !            35: #include       <stdio.h>
        !            36: #include       <errno.h>
        !            37: 
        !            38: #ifdef size_t
        !            39: #undef size_t
        !            40: #endif
        !            41: 
        !            42: #include       <sys/types.h>
        !            43: #ifndef        FILIO_H
        !            44: #include       <sys/ioctl.h>
        !            45: #endif
        !            46: #include       <sys/socket.h>
        !            47: 
        !            48: #include       "ring.h"
        !            49: #include       "general.h"
        !            50: 
        !            51: /* Internal macros */
        !            52: 
        !            53: #if    !defined(MIN)
        !            54: #define        MIN(a,b)        (((a)<(b))? (a):(b))
        !            55: #endif /* !defined(MIN) */
        !            56: 
        !            57: #define        ring_subtract(d,a,b)    (((a)-(b) >= 0)? \
        !            58:                                        (a)-(b): (((a)-(b))+(d)->size))
        !            59: 
        !            60: #define        ring_increment(d,a,c)   (((a)+(c) < (d)->top)? \
        !            61:                                        (a)+(c) : (((a)+(c))-(d)->size))
        !            62: 
        !            63: #define        ring_decrement(d,a,c)   (((a)-(c) >= (d)->bottom)? \
        !            64:                                        (a)-(c) : (((a)-(c))-(d)->size))
        !            65: 
        !            66: 
        !            67: /*
        !            68:  * The following is a clock, used to determine full, empty, etc.
        !            69:  *
        !            70:  * There is some trickiness here.  Since the ring buffers are initialized
        !            71:  * to ZERO on allocation, we need to make sure, when interpreting the
        !            72:  * clock, that when the times are EQUAL, then the buffer is FULL.
        !            73:  */
        !            74: static u_long ring_clock = 0;
        !            75: 
        !            76: 
        !            77: #define        ring_empty(d) (((d)->consume == (d)->supply) && \
        !            78:                                ((d)->consumetime >= (d)->supplytime))
        !            79: #define        ring_full(d) (((d)->supply == (d)->consume) && \
        !            80:                                ((d)->supplytime > (d)->consumetime))
        !            81: 
        !            82: 
        !            83: 
        !            84: 
        !            85: 
        !            86: /* Buffer state transition routines */
        !            87: 
        !            88: ring_init(ring, buffer, count)
        !            89: Ring *ring;
        !            90: char *buffer;
        !            91: int count;
        !            92: {
        !            93:     memset((char *)ring, 0, sizeof *ring);
        !            94: 
        !            95:     ring->size = count;
        !            96: 
        !            97:     ring->supply = ring->consume = ring->bottom = buffer;
        !            98: 
        !            99:     ring->top = ring->bottom+ring->size;
        !           100: 
        !           101:     return 1;
        !           102: }
        !           103: 
        !           104: /* Mark routines */
        !           105: 
        !           106: /*
        !           107:  * Mark the most recently supplied byte.
        !           108:  */
        !           109: 
        !           110: void
        !           111: ring_mark(ring)
        !           112: Ring *ring;
        !           113: {
        !           114:     ring->mark = ring_decrement(ring, ring->supply, 1);
        !           115: }
        !           116: 
        !           117: /*
        !           118:  * Is the ring pointing to the mark?
        !           119:  */
        !           120: 
        !           121: int
        !           122: ring_at_mark(ring)
        !           123: Ring *ring;
        !           124: {
        !           125:     if (ring->mark == ring->consume) {
        !           126:        return 1;
        !           127:     } else {
        !           128:        return 0;
        !           129:     }
        !           130: }
        !           131: 
        !           132: /*
        !           133:  * Clear any mark set on the ring.
        !           134:  */
        !           135: 
        !           136: void
        !           137: ring_clear_mark(ring)
        !           138: Ring *ring;
        !           139: {
        !           140:     ring->mark = 0;
        !           141: }
        !           142: 
        !           143: /*
        !           144:  * Add characters from current segment to ring buffer.
        !           145:  */
        !           146: void
        !           147: ring_supplied(ring, count)
        !           148: Ring *ring;
        !           149: int count;
        !           150: {
        !           151:     ring->supply = ring_increment(ring, ring->supply, count);
        !           152:     ring->supplytime = ++ring_clock;
        !           153: }
        !           154: 
        !           155: /*
        !           156:  * We have just consumed "c" bytes.
        !           157:  */
        !           158: void
        !           159: ring_consumed(ring, count)
        !           160: Ring *ring;
        !           161: int count;
        !           162: {
        !           163:     if (count == 0)    /* don't update anything */
        !           164:        return;
        !           165: 
        !           166:     if (ring->mark &&
        !           167:                (ring_subtract(ring, ring->mark, ring->consume) < count)) {
        !           168:        ring->mark = 0;
        !           169:     }
        !           170:     ring->consume = ring_increment(ring, ring->consume, count);
        !           171:     ring->consumetime = ++ring_clock;
        !           172:     /*
        !           173:      * Try to encourage "ring_empty_consecutive()" to be large.
        !           174:      */
        !           175:     if (ring_empty(ring)) {
        !           176:        ring->consume = ring->supply = ring->bottom;
        !           177:     }
        !           178: }
        !           179: 
        !           180: 
        !           181: 
        !           182: /* Buffer state query routines */
        !           183: 
        !           184: 
        !           185: /* Number of bytes that may be supplied */
        !           186: int
        !           187: ring_empty_count(ring)
        !           188: Ring *ring;
        !           189: {
        !           190:     if (ring_empty(ring)) {    /* if empty */
        !           191:            return ring->size;
        !           192:     } else {
        !           193:        return ring_subtract(ring, ring->consume, ring->supply);
        !           194:     }
        !           195: }
        !           196: 
        !           197: /* number of CONSECUTIVE bytes that may be supplied */
        !           198: int
        !           199: ring_empty_consecutive(ring)
        !           200: Ring *ring;
        !           201: {
        !           202:     if ((ring->consume < ring->supply) || ring_empty(ring)) {
        !           203:                            /*
        !           204:                             * if consume is "below" supply, or empty, then
        !           205:                             * return distance to the top
        !           206:                             */
        !           207:        return ring_subtract(ring, ring->top, ring->supply);
        !           208:     } else {
        !           209:                                    /*
        !           210:                                     * else, return what we may.
        !           211:                                     */
        !           212:        return ring_subtract(ring, ring->consume, ring->supply);
        !           213:     }
        !           214: }
        !           215: 
        !           216: /* Return the number of bytes that are available for consuming
        !           217:  * (but don't give more than enough to get to cross over set mark)
        !           218:  */
        !           219: 
        !           220: int
        !           221: ring_full_count(ring)
        !           222: Ring *ring;
        !           223: {
        !           224:     if ((ring->mark == 0) || (ring->mark == ring->consume)) {
        !           225:        if (ring_full(ring)) {
        !           226:            return ring->size;  /* nothing consumed, but full */
        !           227:        } else {
        !           228:            return ring_subtract(ring, ring->supply, ring->consume);
        !           229:        }
        !           230:     } else {
        !           231:        return ring_subtract(ring, ring->mark, ring->consume);
        !           232:     }
        !           233: }
        !           234: 
        !           235: /*
        !           236:  * Return the number of CONSECUTIVE bytes available for consuming.
        !           237:  * However, don't return more than enough to cross over set mark.
        !           238:  */
        !           239: int
        !           240: ring_full_consecutive(ring)
        !           241: Ring *ring;
        !           242: {
        !           243:     if ((ring->mark == 0) || (ring->mark == ring->consume)) {
        !           244:        if ((ring->supply < ring->consume) || ring_full(ring)) {
        !           245:            return ring_subtract(ring, ring->top, ring->consume);
        !           246:        } else {
        !           247:            return ring_subtract(ring, ring->supply, ring->consume);
        !           248:        }
        !           249:     } else {
        !           250:        if (ring->mark < ring->consume) {
        !           251:            return ring_subtract(ring, ring->top, ring->consume);
        !           252:        } else {        /* Else, distance to mark */
        !           253:            return ring_subtract(ring, ring->mark, ring->consume);
        !           254:        }
        !           255:     }
        !           256: }
        !           257: 
        !           258: /*
        !           259:  * Move data into the "supply" portion of of the ring buffer.
        !           260:  */
        !           261: void
        !           262: ring_supply_data(ring, buffer, count)
        !           263: Ring *ring;
        !           264: char *buffer;
        !           265: int count;
        !           266: {
        !           267:     int i;
        !           268: 
        !           269:     while (count) {
        !           270:        i = MIN(count, ring_empty_consecutive(ring));
        !           271:        memcpy(ring->supply, buffer, i);
        !           272:        ring_supplied(ring, i);
        !           273:        count -= i;
        !           274:        buffer += i;
        !           275:     }
        !           276: }
        !           277: 
        !           278: #ifdef notdef
        !           279: 
        !           280: /*
        !           281:  * Move data from the "consume" portion of the ring buffer
        !           282:  */
        !           283: void
        !           284: ring_consume_data(ring, buffer, count)
        !           285: Ring *ring;
        !           286: char *buffer;
        !           287: int count;
        !           288: {
        !           289:     int i;
        !           290: 
        !           291:     while (count) {
        !           292:        i = MIN(count, ring_full_consecutive(ring));
        !           293:        memcpy(buffer, ring->consume, i);
        !           294:        ring_consumed(ring, i);
        !           295:        count -= i;
        !           296:        buffer += i;
        !           297:     }
        !           298: }
        !           299: #endif

unix.superglobalmegacorp.com

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