132379Sminshall /* 232528Sminshall * This defines a structure for a ring buffer. 332379Sminshall * 432528Sminshall * The circular buffer has two parts: 532379Sminshall *((( 632528Sminshall * full: [consume, supply) 732528Sminshall * 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 4432528Sminshall * clock, that when the times are EQUAL, then the buffer is FULL. 4532379Sminshall */ 4632379Sminshall static u_long ring_clock = 0; 4732379Sminshall 4832379Sminshall 4932528Sminshall #define ring_empty(d) (((d)->consume == (d)->supply) && \ 5032528Sminshall ((d)->consumetime >= (d)->supplytime)) 5132528Sminshall #define ring_full(d) (((d)->supply == (d)->consume) && \ 5232528Sminshall ((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 6932528Sminshall 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 8032528Sminshall ring_supplied(ring, count) 8132379Sminshall Ring *ring; 8232379Sminshall int count; 8332379Sminshall { 8432528Sminshall ring->supply = ring_increment(ring, ring->supply, count); 8532528Sminshall ring->supplytime = ++ring_clock; 8632379Sminshall } 8732379Sminshall 8832379Sminshall /* 8932528Sminshall * We have just consumed "c" bytes. 9032379Sminshall */ 9132379Sminshall void 9232528Sminshall ring_consumed(ring, count) 9332379Sminshall Ring *ring; 9432379Sminshall int count; 9532379Sminshall { 9632528Sminshall ring->consume = ring_increment(ring, ring->consume, count); 9732528Sminshall ring->consumetime = ++ring_clock; 98*32547Sminshall /* 99*32547Sminshall * Try to encourage "ring_empty_consecutive()" to be large. 100*32547Sminshall */ 101*32547Sminshall if (ring_empty(ring)) { 102*32547Sminshall ring->consume = ring->supply = ring->bottom; 103*32547Sminshall } 10432379Sminshall } 10532379Sminshall 10632379Sminshall 10732379Sminshall 10832379Sminshall /* Buffer state query routines */ 10932379Sminshall 11032379Sminshall 11132528Sminshall /* Number of bytes that may be supplied */ 11232379Sminshall int 11332379Sminshall ring_empty_count(ring) 11432379Sminshall Ring *ring; 11532379Sminshall { 11632528Sminshall if (ring_empty(ring)) { /* if empty */ 11732379Sminshall return ring->size; 11832379Sminshall } else { 11932528Sminshall return ring_subtract(ring, ring->consume, ring->supply); 12032379Sminshall } 12132379Sminshall } 12232379Sminshall 12332528Sminshall /* number of CONSECUTIVE bytes that may be supplied */ 12432379Sminshall int 12532379Sminshall ring_empty_consecutive(ring) 12632379Sminshall Ring *ring; 12732379Sminshall { 12832528Sminshall if ((ring->consume < ring->supply) || ring_empty(ring)) { 12932528Sminshall /* 13032528Sminshall * if consume is "below" supply, or empty, then 13132528Sminshall * return distance to the top 13232528Sminshall */ 13332528Sminshall return ring_subtract(ring, ring->top, ring->supply); 13432379Sminshall } else { 13532379Sminshall /* 13632379Sminshall * else, return what we may. 13732379Sminshall */ 13832528Sminshall return ring_subtract(ring, ring->consume, ring->supply); 13932379Sminshall } 14032379Sminshall } 14132379Sminshall 14232528Sminshall /* number of bytes that are available for consuming */ 14332379Sminshall int 14432528Sminshall ring_full_count(ring) 14532379Sminshall Ring *ring; 14632379Sminshall { 14732528Sminshall if (ring_full(ring)) { 14832528Sminshall return ring->size; /* nothing consumed, but full */ 14932379Sminshall } else { 15032528Sminshall return ring_subtract(ring, ring->supply, ring->consume); 15132379Sminshall } 15232379Sminshall } 15332379Sminshall 15432528Sminshall /* number of CONSECUTIVE bytes available for consuming */ 15532379Sminshall int 15632528Sminshall ring_full_consecutive(ring) 15732379Sminshall Ring *ring; 15832379Sminshall { 15932528Sminshall if ((ring->supply < ring->consume) || ring_full(ring)) { 16032528Sminshall return ring_subtract(ring, ring->top, ring->consume); 16132379Sminshall } else { 16232528Sminshall return ring_subtract(ring, ring->supply, ring->consume); 16332379Sminshall } 16432379Sminshall } 16532379Sminshall 16632379Sminshall /* 16732528Sminshall * Move data into the "supply" portion of of the ring buffer. 16832379Sminshall */ 16932379Sminshall void 17032528Sminshall ring_supply_data(ring, buffer, count) 17132379Sminshall Ring *ring; 17232379Sminshall char *buffer; 17332379Sminshall int count; 17432379Sminshall { 17532379Sminshall int i; 17632379Sminshall 17732379Sminshall while (count) { 17832381Sminshall i = MIN(count, ring_empty_consecutive(ring)); 17932528Sminshall memcpy(ring->supply, buffer, i); 18032528Sminshall ring_supplied(ring, i); 18132379Sminshall count -= i; 18232379Sminshall buffer += i; 18332379Sminshall } 18432379Sminshall } 18532379Sminshall 18632379Sminshall 18732379Sminshall /* 18832528Sminshall * Move data from the "consume" portion of the ring buffer 18932379Sminshall */ 19032379Sminshall void 19132528Sminshall ring_consume_data(ring, buffer, count) 19232379Sminshall Ring *ring; 19332379Sminshall char *buffer; 19432379Sminshall int count; 19532379Sminshall { 19632379Sminshall int i; 19732379Sminshall 19832379Sminshall while (count) { 19932528Sminshall i = MIN(count, ring_full_consecutive(ring)); 20032528Sminshall memcpy(buffer, ring->consume, i); 20132528Sminshall ring_consumed(ring, i); 20232379Sminshall count -= i; 20332379Sminshall buffer += i; 20432379Sminshall } 20532379Sminshall } 20632381Sminshall 20732381Sminshall /* Mark routines */ 20832381Sminshall 20932381Sminshall /* XXX do something here */ 21032381Sminshall void 21132381Sminshall ring_mark(ring) 21232381Sminshall Ring *ring; 21332381Sminshall { 21432381Sminshall } 21532381Sminshall 21632381Sminshall int 21732381Sminshall ring_at_mark(ring) 21832381Sminshall Ring *ring; 21932381Sminshall { 22032381Sminshall return 0; 22132381Sminshall } 22232381Sminshall 22332381Sminshall void 22432381Sminshall ring_clear_mark(ring) 22532381Sminshall Ring *ring; 22632381Sminshall { 22732381Sminshall } 228