132379Sminshall /* 2*32528Sminshall * This defines a structure for a ring buffer. 332379Sminshall * 4*32528Sminshall * The circular buffer has two parts: 532379Sminshall *((( 6*32528Sminshall * full: [consume, supply) 7*32528Sminshall * empty: [supply, consume) 832379Sminshall *]]] 932379Sminshall * 1032379Sminshall */ 1132379Sminshall 1232379Sminshall #include <stdio.h> 1332379Sminshall #include <errno.h> 1432379Sminshall 1532379Sminshall #ifdef size_t 1632379Sminshall #undef size_t 1732379Sminshall #endif 1832379Sminshall 1932379Sminshall #include <sys/types.h> 2032379Sminshall #include <sys/ioctl.h> 2132379Sminshall #include <sys/socket.h> 2232379Sminshall 2332379Sminshall #include "ring.h" 2432379Sminshall #include "general.h" 2532379Sminshall 2632379Sminshall /* Internal macros */ 2732379Sminshall 2832381Sminshall #if !defined(MIN) 2932381Sminshall #define MIN(a,b) (((a)<(b))? (a):(b)) 3032381Sminshall #endif /* !defined(MIN) */ 3132379Sminshall 3232381Sminshall #define ring_subtract(d,a,b) ((((int)(a))-((int)(b)) >= 0)? \ 3332381Sminshall (a)-(b): (((a)-(b))+(d)->size)) 3432379Sminshall 3532379Sminshall #define ring_increment(d,a,c) (((a)+(c) < (d)->top)? \ 3632379Sminshall (a)+(c) : (((a)+(c))-(d)->size)) 3732379Sminshall 3832379Sminshall 3932379Sminshall /* 4032379Sminshall * The following is a clock, used to determine full, empty, etc. 4132379Sminshall * 4232379Sminshall * There is some trickiness here. Since the ring buffers are initialized 4332379Sminshall * to ZERO on allocation, we need to make sure, when interpreting the 44*32528Sminshall * clock, that when the times are EQUAL, then the buffer is FULL. 4532379Sminshall */ 4632379Sminshall static u_long ring_clock = 0; 4732379Sminshall 4832379Sminshall 49*32528Sminshall #define ring_empty(d) (((d)->consume == (d)->supply) && \ 50*32528Sminshall ((d)->consumetime >= (d)->supplytime)) 51*32528Sminshall #define ring_full(d) (((d)->supply == (d)->consume) && \ 52*32528Sminshall ((d)->supplytime > (d)->consumetime)) 5332379Sminshall 5432379Sminshall 5532379Sminshall 5632379Sminshall 5732379Sminshall 5832379Sminshall /* Buffer state transition routines */ 5932379Sminshall 6032381Sminshall ring_init(ring, buffer, count) 6132381Sminshall Ring *ring; 6232381Sminshall char *buffer; 6332381Sminshall int count; 6432381Sminshall { 6532381Sminshall memset((char *)ring, 0, sizeof *ring); 6632379Sminshall 6732381Sminshall ring->size = count; 6832381Sminshall 69*32528Sminshall ring->supply = ring->consume = ring->bottom = buffer; 7032381Sminshall 7132381Sminshall ring->top = ring->bottom+ring->size; 7232381Sminshall 7332381Sminshall return 1; 7432381Sminshall } 7532381Sminshall 7632379Sminshall /* 7732379Sminshall * Add characters from current segment to ring buffer. 7832379Sminshall */ 7932379Sminshall void 80*32528Sminshall ring_supplied(ring, count) 8132379Sminshall Ring *ring; 8232379Sminshall int count; 8332379Sminshall { 84*32528Sminshall ring->supply = ring_increment(ring, ring->supply, count); 85*32528Sminshall ring->supplytime = ++ring_clock; 8632379Sminshall } 8732379Sminshall 8832379Sminshall /* 89*32528Sminshall * We have just consumed "c" bytes. 9032379Sminshall */ 9132379Sminshall void 92*32528Sminshall ring_consumed(ring, count) 9332379Sminshall Ring *ring; 9432379Sminshall int count; 9532379Sminshall { 96*32528Sminshall ring->consume = ring_increment(ring, ring->consume, count); 97*32528Sminshall ring->consumetime = ++ring_clock; 9832379Sminshall } 9932379Sminshall 10032379Sminshall 10132379Sminshall 10232379Sminshall /* Buffer state query routines */ 10332379Sminshall 10432379Sminshall 105*32528Sminshall /* Number of bytes that may be supplied */ 10632379Sminshall int 10732379Sminshall ring_empty_count(ring) 10832379Sminshall Ring *ring; 10932379Sminshall { 110*32528Sminshall if (ring_empty(ring)) { /* if empty */ 11132379Sminshall return ring->size; 11232379Sminshall } else { 113*32528Sminshall return ring_subtract(ring, ring->consume, ring->supply); 11432379Sminshall } 11532379Sminshall } 11632379Sminshall 117*32528Sminshall /* number of CONSECUTIVE bytes that may be supplied */ 11832379Sminshall int 11932379Sminshall ring_empty_consecutive(ring) 12032379Sminshall Ring *ring; 12132379Sminshall { 122*32528Sminshall if ((ring->consume < ring->supply) || ring_empty(ring)) { 123*32528Sminshall /* 124*32528Sminshall * if consume is "below" supply, or empty, then 125*32528Sminshall * return distance to the top 126*32528Sminshall */ 127*32528Sminshall return ring_subtract(ring, ring->top, ring->supply); 12832379Sminshall } else { 12932379Sminshall /* 13032379Sminshall * else, return what we may. 13132379Sminshall */ 132*32528Sminshall return ring_subtract(ring, ring->consume, ring->supply); 13332379Sminshall } 13432379Sminshall } 13532379Sminshall 136*32528Sminshall /* number of bytes that are available for consuming */ 13732379Sminshall int 138*32528Sminshall ring_full_count(ring) 13932379Sminshall Ring *ring; 14032379Sminshall { 141*32528Sminshall if (ring_full(ring)) { 142*32528Sminshall return ring->size; /* nothing consumed, but full */ 14332379Sminshall } else { 144*32528Sminshall return ring_subtract(ring, ring->supply, ring->consume); 14532379Sminshall } 14632379Sminshall } 14732379Sminshall 148*32528Sminshall /* number of CONSECUTIVE bytes available for consuming */ 14932379Sminshall int 150*32528Sminshall ring_full_consecutive(ring) 15132379Sminshall Ring *ring; 15232379Sminshall { 153*32528Sminshall if ((ring->supply < ring->consume) || ring_full(ring)) { 154*32528Sminshall return ring_subtract(ring, ring->top, ring->consume); 15532379Sminshall } else { 156*32528Sminshall return ring_subtract(ring, ring->supply, ring->consume); 15732379Sminshall } 15832379Sminshall } 15932379Sminshall 16032379Sminshall /* 161*32528Sminshall * Move data into the "supply" portion of of the ring buffer. 16232379Sminshall */ 16332379Sminshall void 164*32528Sminshall ring_supply_data(ring, buffer, count) 16532379Sminshall Ring *ring; 16632379Sminshall char *buffer; 16732379Sminshall int count; 16832379Sminshall { 16932379Sminshall int i; 17032379Sminshall 17132379Sminshall while (count) { 17232381Sminshall i = MIN(count, ring_empty_consecutive(ring)); 173*32528Sminshall memcpy(ring->supply, buffer, i); 174*32528Sminshall ring_supplied(ring, i); 17532379Sminshall count -= i; 17632379Sminshall buffer += i; 17732379Sminshall } 17832379Sminshall } 17932379Sminshall 18032379Sminshall 18132379Sminshall /* 182*32528Sminshall * Move data from the "consume" portion of the ring buffer 18332379Sminshall */ 18432379Sminshall void 185*32528Sminshall ring_consume_data(ring, buffer, count) 18632379Sminshall Ring *ring; 18732379Sminshall char *buffer; 18832379Sminshall int count; 18932379Sminshall { 19032379Sminshall int i; 19132379Sminshall 19232379Sminshall while (count) { 193*32528Sminshall i = MIN(count, ring_full_consecutive(ring)); 194*32528Sminshall memcpy(buffer, ring->consume, i); 195*32528Sminshall ring_consumed(ring, i); 19632379Sminshall count -= i; 19732379Sminshall buffer += i; 19832379Sminshall } 19932379Sminshall } 20032381Sminshall 20132381Sminshall /* Mark routines */ 20232381Sminshall 20332381Sminshall /* XXX do something here */ 20432381Sminshall void 20532381Sminshall ring_mark(ring) 20632381Sminshall Ring *ring; 20732381Sminshall { 20832381Sminshall } 20932381Sminshall 21032381Sminshall int 21132381Sminshall ring_at_mark(ring) 21232381Sminshall Ring *ring; 21332381Sminshall { 21432381Sminshall return 0; 21532381Sminshall } 21632381Sminshall 21732381Sminshall void 21832381Sminshall ring_clear_mark(ring) 21932381Sminshall Ring *ring; 22032381Sminshall { 22132381Sminshall } 222