17c478bd9Sstevel@tonic-gate /* 2*740638c8Sbw * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 37c478bd9Sstevel@tonic-gate * Use is subject to license terms. 47c478bd9Sstevel@tonic-gate */ 57c478bd9Sstevel@tonic-gate 67c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 77c478bd9Sstevel@tonic-gate 87c478bd9Sstevel@tonic-gate /* 97c478bd9Sstevel@tonic-gate * usr/src/cmd/cmd-inet/usr.bin/telnet/ring.c 107c478bd9Sstevel@tonic-gate */ 117c478bd9Sstevel@tonic-gate 127c478bd9Sstevel@tonic-gate /* 137c478bd9Sstevel@tonic-gate * Copyright (c) 1988, 1993 147c478bd9Sstevel@tonic-gate * The Regents of the University of California. All rights reserved. 157c478bd9Sstevel@tonic-gate * 167c478bd9Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without 177c478bd9Sstevel@tonic-gate * modification, are permitted provided that the following conditions 187c478bd9Sstevel@tonic-gate * are met: 197c478bd9Sstevel@tonic-gate * 1. Redistributions of source code must retain the above copyright 207c478bd9Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer. 217c478bd9Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright 227c478bd9Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in the 237c478bd9Sstevel@tonic-gate * documentation and/or other materials provided with the distribution. 247c478bd9Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this software 257c478bd9Sstevel@tonic-gate * must display the following acknowledgement: 267c478bd9Sstevel@tonic-gate * This product includes software developed by the University of 277c478bd9Sstevel@tonic-gate * California, Berkeley and its contributors. 287c478bd9Sstevel@tonic-gate * 4. Neither the name of the University nor the names of its contributors 297c478bd9Sstevel@tonic-gate * may be used to endorse or promote products derived from this software 307c478bd9Sstevel@tonic-gate * without specific prior written permission. 317c478bd9Sstevel@tonic-gate * 327c478bd9Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 337c478bd9Sstevel@tonic-gate * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 347c478bd9Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 357c478bd9Sstevel@tonic-gate * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 367c478bd9Sstevel@tonic-gate * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 377c478bd9Sstevel@tonic-gate * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 387c478bd9Sstevel@tonic-gate * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 397c478bd9Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 407c478bd9Sstevel@tonic-gate * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 417c478bd9Sstevel@tonic-gate * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 427c478bd9Sstevel@tonic-gate * SUCH DAMAGE. 437c478bd9Sstevel@tonic-gate */ 447c478bd9Sstevel@tonic-gate 457c478bd9Sstevel@tonic-gate #ifndef lint 467c478bd9Sstevel@tonic-gate static char sccsid[] = "@(#)ring.c 8.1 (Berkeley) 6/6/93"; 477c478bd9Sstevel@tonic-gate #endif /* not lint */ 487c478bd9Sstevel@tonic-gate 497c478bd9Sstevel@tonic-gate /* 507c478bd9Sstevel@tonic-gate * This defines a structure for a ring buffer. 517c478bd9Sstevel@tonic-gate * 527c478bd9Sstevel@tonic-gate * The circular buffer has two parts: 537c478bd9Sstevel@tonic-gate * ((( 547c478bd9Sstevel@tonic-gate * full: [consume, supply) 557c478bd9Sstevel@tonic-gate * empty: [supply, consume) 567c478bd9Sstevel@tonic-gate * ]]] 577c478bd9Sstevel@tonic-gate * 587c478bd9Sstevel@tonic-gate */ 597c478bd9Sstevel@tonic-gate 607c478bd9Sstevel@tonic-gate #include <stdio.h> 617c478bd9Sstevel@tonic-gate #include <errno.h> 627c478bd9Sstevel@tonic-gate #include <string.h> 637c478bd9Sstevel@tonic-gate 647c478bd9Sstevel@tonic-gate #include <sys/types.h> 657c478bd9Sstevel@tonic-gate #include <sys/socket.h> 667c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h> 677c478bd9Sstevel@tonic-gate 687c478bd9Sstevel@tonic-gate #include "ring.h" 697c478bd9Sstevel@tonic-gate #include "general.h" 707c478bd9Sstevel@tonic-gate 717c478bd9Sstevel@tonic-gate 727c478bd9Sstevel@tonic-gate #define ring_subtract(d, a, b) (((a)-(b) >= 0)? \ 737c478bd9Sstevel@tonic-gate (a)-(b): (((a)-(b))+(d)->size)) 747c478bd9Sstevel@tonic-gate 757c478bd9Sstevel@tonic-gate #define ring_increment(d, a, c) (((a)+(c) < (d)->top)? \ 767c478bd9Sstevel@tonic-gate (a)+(c) : (((a)+(c))-(d)->size)) 777c478bd9Sstevel@tonic-gate 787c478bd9Sstevel@tonic-gate #define ring_decrement(d, a, c) (((a)-(c) >= (d)->bottom)? \ 797c478bd9Sstevel@tonic-gate (a)-(c) : (((a)-(c))-(d)->size)) 807c478bd9Sstevel@tonic-gate 817c478bd9Sstevel@tonic-gate 827c478bd9Sstevel@tonic-gate /* 837c478bd9Sstevel@tonic-gate * The following is a clock, used to determine full, empty, etc. 847c478bd9Sstevel@tonic-gate * 857c478bd9Sstevel@tonic-gate * There is some trickiness here. Since the ring buffers are initialized 867c478bd9Sstevel@tonic-gate * to ZERO on allocation, we need to make sure, when interpreting the 877c478bd9Sstevel@tonic-gate * clock, that when the times are EQUAL, then the buffer is FULL. 887c478bd9Sstevel@tonic-gate */ 897c478bd9Sstevel@tonic-gate ulong_t ring_clock = 0; 907c478bd9Sstevel@tonic-gate 917c478bd9Sstevel@tonic-gate 927c478bd9Sstevel@tonic-gate #define ring_empty(d) (((d)->consume == (d)->supply) && \ 937c478bd9Sstevel@tonic-gate ((d)->consumetime >= (d)->supplytime)) 947c478bd9Sstevel@tonic-gate #define ring_full(d) (((d)->supply == (d)->consume) && \ 957c478bd9Sstevel@tonic-gate ((d)->supplytime > (d)->consumetime)) 967c478bd9Sstevel@tonic-gate 977c478bd9Sstevel@tonic-gate 987c478bd9Sstevel@tonic-gate 997c478bd9Sstevel@tonic-gate 1007c478bd9Sstevel@tonic-gate 1017c478bd9Sstevel@tonic-gate /* Buffer state transition routines */ 1027c478bd9Sstevel@tonic-gate 103*740638c8Sbw int 1047c478bd9Sstevel@tonic-gate ring_init(ring, buffer, count) 1057c478bd9Sstevel@tonic-gate Ring *ring; 1067c478bd9Sstevel@tonic-gate unsigned char *buffer; 1077c478bd9Sstevel@tonic-gate int count; 1087c478bd9Sstevel@tonic-gate { 1097c478bd9Sstevel@tonic-gate (void) memset(ring, 0, sizeof (*ring)); 1107c478bd9Sstevel@tonic-gate 1117c478bd9Sstevel@tonic-gate ring->size = count; 1127c478bd9Sstevel@tonic-gate 1137c478bd9Sstevel@tonic-gate ring->supply = ring->consume = ring->bottom = buffer; 1147c478bd9Sstevel@tonic-gate 1157c478bd9Sstevel@tonic-gate ring->top = ring->bottom+ring->size; 1167c478bd9Sstevel@tonic-gate 1177c478bd9Sstevel@tonic-gate ring->clearto = 0; 1187c478bd9Sstevel@tonic-gate 1197c478bd9Sstevel@tonic-gate return (1); 1207c478bd9Sstevel@tonic-gate } 1217c478bd9Sstevel@tonic-gate 1227c478bd9Sstevel@tonic-gate /* Mark routines */ 1237c478bd9Sstevel@tonic-gate 1247c478bd9Sstevel@tonic-gate /* 1257c478bd9Sstevel@tonic-gate * Mark the most recently supplied byte. 1267c478bd9Sstevel@tonic-gate */ 1277c478bd9Sstevel@tonic-gate 1287c478bd9Sstevel@tonic-gate void 1297c478bd9Sstevel@tonic-gate ring_mark(ring) 1307c478bd9Sstevel@tonic-gate Ring *ring; 1317c478bd9Sstevel@tonic-gate { 1327c478bd9Sstevel@tonic-gate ring->mark = ring_decrement(ring, ring->supply, 1); 1337c478bd9Sstevel@tonic-gate } 1347c478bd9Sstevel@tonic-gate 1357c478bd9Sstevel@tonic-gate /* 1367c478bd9Sstevel@tonic-gate * Is the ring pointing to the mark? 1377c478bd9Sstevel@tonic-gate */ 1387c478bd9Sstevel@tonic-gate 1397c478bd9Sstevel@tonic-gate int 1407c478bd9Sstevel@tonic-gate ring_at_mark(ring) 1417c478bd9Sstevel@tonic-gate Ring *ring; 1427c478bd9Sstevel@tonic-gate { 1437c478bd9Sstevel@tonic-gate if (ring->mark == ring->consume) { 1447c478bd9Sstevel@tonic-gate return (1); 1457c478bd9Sstevel@tonic-gate } else { 1467c478bd9Sstevel@tonic-gate return (0); 1477c478bd9Sstevel@tonic-gate } 1487c478bd9Sstevel@tonic-gate } 1497c478bd9Sstevel@tonic-gate 1507c478bd9Sstevel@tonic-gate /* 1517c478bd9Sstevel@tonic-gate * Clear any mark set on the ring. 1527c478bd9Sstevel@tonic-gate */ 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate void 1557c478bd9Sstevel@tonic-gate ring_clear_mark(ring) 1567c478bd9Sstevel@tonic-gate Ring *ring; 1577c478bd9Sstevel@tonic-gate { 1587c478bd9Sstevel@tonic-gate ring->mark = 0; 1597c478bd9Sstevel@tonic-gate } 1607c478bd9Sstevel@tonic-gate 1617c478bd9Sstevel@tonic-gate /* 1627c478bd9Sstevel@tonic-gate * Add characters from current segment to ring buffer. 1637c478bd9Sstevel@tonic-gate */ 1647c478bd9Sstevel@tonic-gate void 1657c478bd9Sstevel@tonic-gate ring_supplied(ring, count) 1667c478bd9Sstevel@tonic-gate Ring *ring; 1677c478bd9Sstevel@tonic-gate int count; 1687c478bd9Sstevel@tonic-gate { 1697c478bd9Sstevel@tonic-gate ring->supply = ring_increment(ring, ring->supply, count); 1707c478bd9Sstevel@tonic-gate ring->supplytime = ++ring_clock; 1717c478bd9Sstevel@tonic-gate } 1727c478bd9Sstevel@tonic-gate 1737c478bd9Sstevel@tonic-gate /* 1747c478bd9Sstevel@tonic-gate * We have just consumed "c" bytes. 1757c478bd9Sstevel@tonic-gate */ 1767c478bd9Sstevel@tonic-gate void 1777c478bd9Sstevel@tonic-gate ring_consumed(ring, count) 1787c478bd9Sstevel@tonic-gate Ring *ring; 1797c478bd9Sstevel@tonic-gate int count; 1807c478bd9Sstevel@tonic-gate { 1817c478bd9Sstevel@tonic-gate if (count == 0) /* don't update anything */ 1827c478bd9Sstevel@tonic-gate return; 1837c478bd9Sstevel@tonic-gate 1847c478bd9Sstevel@tonic-gate if (ring->mark && 1857c478bd9Sstevel@tonic-gate (ring_subtract(ring, ring->mark, ring->consume) < count)) { 1867c478bd9Sstevel@tonic-gate ring->mark = 0; 1877c478bd9Sstevel@tonic-gate } 1887c478bd9Sstevel@tonic-gate 1897c478bd9Sstevel@tonic-gate if (ring->consume < ring->clearto && 1907c478bd9Sstevel@tonic-gate ring->clearto <= ring->consume + count) 1917c478bd9Sstevel@tonic-gate ring->clearto = 0; 1927c478bd9Sstevel@tonic-gate else if (ring->consume + count > ring->top && 1937c478bd9Sstevel@tonic-gate ring->bottom <= ring->clearto && 1947c478bd9Sstevel@tonic-gate ring->bottom + ((ring->consume + count) - ring->top)) 1957c478bd9Sstevel@tonic-gate ring->clearto = 0; 1967c478bd9Sstevel@tonic-gate 1977c478bd9Sstevel@tonic-gate ring->consume = ring_increment(ring, ring->consume, count); 1987c478bd9Sstevel@tonic-gate ring->consumetime = ++ring_clock; 1997c478bd9Sstevel@tonic-gate /* 2007c478bd9Sstevel@tonic-gate * Try to encourage "ring_empty_consecutive()" to be large. 2017c478bd9Sstevel@tonic-gate */ 2027c478bd9Sstevel@tonic-gate if (ring_empty(ring)) { 2037c478bd9Sstevel@tonic-gate ring->consume = ring->supply = ring->bottom; 2047c478bd9Sstevel@tonic-gate } 2057c478bd9Sstevel@tonic-gate } 2067c478bd9Sstevel@tonic-gate 2077c478bd9Sstevel@tonic-gate 2087c478bd9Sstevel@tonic-gate 2097c478bd9Sstevel@tonic-gate /* Buffer state query routines */ 2107c478bd9Sstevel@tonic-gate 2117c478bd9Sstevel@tonic-gate 2127c478bd9Sstevel@tonic-gate /* Number of bytes that may be supplied */ 2137c478bd9Sstevel@tonic-gate int 2147c478bd9Sstevel@tonic-gate ring_empty_count(ring) 2157c478bd9Sstevel@tonic-gate Ring *ring; 2167c478bd9Sstevel@tonic-gate { 2177c478bd9Sstevel@tonic-gate if (ring_empty(ring)) { /* if empty */ 2187c478bd9Sstevel@tonic-gate return (ring->size); 2197c478bd9Sstevel@tonic-gate } else { 2207c478bd9Sstevel@tonic-gate return (ring_subtract(ring, ring->consume, ring->supply)); 2217c478bd9Sstevel@tonic-gate } 2227c478bd9Sstevel@tonic-gate } 2237c478bd9Sstevel@tonic-gate 2247c478bd9Sstevel@tonic-gate /* number of CONSECUTIVE bytes that may be supplied */ 2257c478bd9Sstevel@tonic-gate int 2267c478bd9Sstevel@tonic-gate ring_empty_consecutive(ring) 2277c478bd9Sstevel@tonic-gate Ring *ring; 2287c478bd9Sstevel@tonic-gate { 2297c478bd9Sstevel@tonic-gate if ((ring->consume < ring->supply) || ring_empty(ring)) { 2307c478bd9Sstevel@tonic-gate /* 2317c478bd9Sstevel@tonic-gate * if consume is "below" supply, or empty, then 2327c478bd9Sstevel@tonic-gate * return distance to the top 2337c478bd9Sstevel@tonic-gate */ 2347c478bd9Sstevel@tonic-gate return (ring_subtract(ring, ring->top, ring->supply)); 2357c478bd9Sstevel@tonic-gate } else { 2367c478bd9Sstevel@tonic-gate /* 2377c478bd9Sstevel@tonic-gate * else, return what we may. 2387c478bd9Sstevel@tonic-gate */ 2397c478bd9Sstevel@tonic-gate return (ring_subtract(ring, ring->consume, ring->supply)); 2407c478bd9Sstevel@tonic-gate } 2417c478bd9Sstevel@tonic-gate } 2427c478bd9Sstevel@tonic-gate 2437c478bd9Sstevel@tonic-gate /* 2447c478bd9Sstevel@tonic-gate * Return the number of bytes that are available for consuming 2457c478bd9Sstevel@tonic-gate * (but don't give more than enough to get to cross over set mark) 2467c478bd9Sstevel@tonic-gate */ 2477c478bd9Sstevel@tonic-gate 2487c478bd9Sstevel@tonic-gate int 2497c478bd9Sstevel@tonic-gate ring_full_count(ring) 2507c478bd9Sstevel@tonic-gate Ring *ring; 2517c478bd9Sstevel@tonic-gate { 2527c478bd9Sstevel@tonic-gate if ((ring->mark == 0) || (ring->mark == ring->consume)) { 2537c478bd9Sstevel@tonic-gate if (ring_full(ring)) { 2547c478bd9Sstevel@tonic-gate return (ring->size); /* nothing consumed, but full */ 2557c478bd9Sstevel@tonic-gate } else { 2567c478bd9Sstevel@tonic-gate return (ring_subtract(ring, ring->supply, 2577c478bd9Sstevel@tonic-gate ring->consume)); 2587c478bd9Sstevel@tonic-gate } 2597c478bd9Sstevel@tonic-gate } else { 2607c478bd9Sstevel@tonic-gate return (ring_subtract(ring, ring->mark, ring->consume)); 2617c478bd9Sstevel@tonic-gate } 2627c478bd9Sstevel@tonic-gate } 2637c478bd9Sstevel@tonic-gate 2647c478bd9Sstevel@tonic-gate /* 2657c478bd9Sstevel@tonic-gate * Return the number of CONSECUTIVE bytes available for consuming. 2667c478bd9Sstevel@tonic-gate * However, don't return more than enough to cross over set mark. 2677c478bd9Sstevel@tonic-gate */ 2687c478bd9Sstevel@tonic-gate int 2697c478bd9Sstevel@tonic-gate ring_full_consecutive(ring) 2707c478bd9Sstevel@tonic-gate Ring *ring; 2717c478bd9Sstevel@tonic-gate { 2727c478bd9Sstevel@tonic-gate if ((ring->mark == 0) || (ring->mark == ring->consume)) { 2737c478bd9Sstevel@tonic-gate if ((ring->supply < ring->consume) || ring_full(ring)) { 2747c478bd9Sstevel@tonic-gate return (ring_subtract(ring, ring->top, ring->consume)); 2757c478bd9Sstevel@tonic-gate } else { 2767c478bd9Sstevel@tonic-gate return (ring_subtract(ring, ring->supply, 2777c478bd9Sstevel@tonic-gate ring->consume)); 2787c478bd9Sstevel@tonic-gate } 2797c478bd9Sstevel@tonic-gate } else { 2807c478bd9Sstevel@tonic-gate if (ring->mark < ring->consume) { 2817c478bd9Sstevel@tonic-gate return (ring_subtract(ring, ring->top, ring->consume)); 2827c478bd9Sstevel@tonic-gate } else { /* Else, distance to mark */ 2837c478bd9Sstevel@tonic-gate return (ring_subtract(ring, ring->mark, ring->consume)); 2847c478bd9Sstevel@tonic-gate } 2857c478bd9Sstevel@tonic-gate } 2867c478bd9Sstevel@tonic-gate } 2877c478bd9Sstevel@tonic-gate 2887c478bd9Sstevel@tonic-gate /* 2897c478bd9Sstevel@tonic-gate * Move data into the "supply" portion of of the ring buffer. 2907c478bd9Sstevel@tonic-gate */ 2917c478bd9Sstevel@tonic-gate void 2927c478bd9Sstevel@tonic-gate ring_supply_data(ring, buffer, count) 2937c478bd9Sstevel@tonic-gate Ring *ring; 2947c478bd9Sstevel@tonic-gate unsigned char *buffer; 2957c478bd9Sstevel@tonic-gate int count; 2967c478bd9Sstevel@tonic-gate { 2977c478bd9Sstevel@tonic-gate int i; 2987c478bd9Sstevel@tonic-gate 2997c478bd9Sstevel@tonic-gate while (count) { 3007c478bd9Sstevel@tonic-gate i = MIN(count, ring_empty_consecutive(ring)); 3017c478bd9Sstevel@tonic-gate (void) memcpy(ring->supply, buffer, i); 3027c478bd9Sstevel@tonic-gate ring_supplied(ring, i); 3037c478bd9Sstevel@tonic-gate count -= i; 3047c478bd9Sstevel@tonic-gate buffer += i; 3057c478bd9Sstevel@tonic-gate } 3067c478bd9Sstevel@tonic-gate } 3077c478bd9Sstevel@tonic-gate 3087c478bd9Sstevel@tonic-gate #ifdef notdef 3097c478bd9Sstevel@tonic-gate 3107c478bd9Sstevel@tonic-gate /* 3117c478bd9Sstevel@tonic-gate * Move data from the "consume" portion of the ring buffer 3127c478bd9Sstevel@tonic-gate */ 3137c478bd9Sstevel@tonic-gate void 3147c478bd9Sstevel@tonic-gate ring_consume_data(ring, buffer, count) 3157c478bd9Sstevel@tonic-gate Ring *ring; 3167c478bd9Sstevel@tonic-gate unsigned char *buffer; 3177c478bd9Sstevel@tonic-gate int count; 3187c478bd9Sstevel@tonic-gate { 3197c478bd9Sstevel@tonic-gate int i; 3207c478bd9Sstevel@tonic-gate 3217c478bd9Sstevel@tonic-gate while (count) { 3227c478bd9Sstevel@tonic-gate i = MIN(count, ring_full_consecutive(ring)); 3237c478bd9Sstevel@tonic-gate memcpy(buffer, ring->consume, i); 3247c478bd9Sstevel@tonic-gate ring_consumed(ring, i); 3257c478bd9Sstevel@tonic-gate count -= i; 3267c478bd9Sstevel@tonic-gate buffer += i; 3277c478bd9Sstevel@tonic-gate } 3287c478bd9Sstevel@tonic-gate } 3297c478bd9Sstevel@tonic-gate #endif 3307c478bd9Sstevel@tonic-gate 3317c478bd9Sstevel@tonic-gate void 3327c478bd9Sstevel@tonic-gate ring_encrypt(ring, encryptor) 3337c478bd9Sstevel@tonic-gate Ring *ring; 3347c478bd9Sstevel@tonic-gate void (*encryptor)(); 3357c478bd9Sstevel@tonic-gate { 3367c478bd9Sstevel@tonic-gate unsigned char *s, *c; 3377c478bd9Sstevel@tonic-gate 3387c478bd9Sstevel@tonic-gate if (ring_empty(ring) || ring->clearto == ring->supply) 3397c478bd9Sstevel@tonic-gate return; 3407c478bd9Sstevel@tonic-gate 3417c478bd9Sstevel@tonic-gate if ((c = ring->clearto) == NULL) 3427c478bd9Sstevel@tonic-gate c = ring->consume; 3437c478bd9Sstevel@tonic-gate 3447c478bd9Sstevel@tonic-gate s = ring->supply; 3457c478bd9Sstevel@tonic-gate 3467c478bd9Sstevel@tonic-gate if (s <= c) { 3477c478bd9Sstevel@tonic-gate (*encryptor)(c, ring->top - c); 3487c478bd9Sstevel@tonic-gate (*encryptor)(ring->bottom, s - ring->bottom); 3497c478bd9Sstevel@tonic-gate } else 3507c478bd9Sstevel@tonic-gate (*encryptor)(c, s - c); 3517c478bd9Sstevel@tonic-gate 3527c478bd9Sstevel@tonic-gate ring->clearto = ring->supply; 3537c478bd9Sstevel@tonic-gate } 3547c478bd9Sstevel@tonic-gate 3557c478bd9Sstevel@tonic-gate void 3567c478bd9Sstevel@tonic-gate ring_clearto(ring) 3577c478bd9Sstevel@tonic-gate Ring *ring; 3587c478bd9Sstevel@tonic-gate { 3597c478bd9Sstevel@tonic-gate if (!ring_empty(ring)) 3607c478bd9Sstevel@tonic-gate ring->clearto = ring->supply; 3617c478bd9Sstevel@tonic-gate else 3627c478bd9Sstevel@tonic-gate ring->clearto = 0; 3637c478bd9Sstevel@tonic-gate } 364