From: Mikko Rasa Date: Wed, 23 Oct 2013 21:02:11 +0000 (+0300) Subject: Add ring buffer utilities X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=cd913ccb15a71d793ccd701d3ab8b39a0efeb23a;p=model-railway-devices.git Add ring buffer utilities These are cropping up all over the place in arducontrol. --- diff --git a/common/ringbuffer.h b/common/ringbuffer.h new file mode 100644 index 0000000..1a03ec5 --- /dev/null +++ b/common/ringbuffer.h @@ -0,0 +1,53 @@ +#ifndef RINGBUFFER_H_ +#define RINGBUFFER_H_ + +#define RINGBUFFER(name, size) uint8_t name[(size)+4] = { size, 0, 0, 0 } + +static inline uint8_t ringbuffer_fill(const uint8_t *buffer) +{ + return buffer[1]; +} + +static inline uint8_t ringbuffer_space(const uint8_t *buffer) +{ + return buffer[0]-buffer[1]; +} + +static inline void ringbuffer_push(uint8_t *buffer, uint8_t value) +{ + const uint8_t size = buffer[0]; + uint8_t head = buffer[2]; + buffer[4+head++] = value; + if(head>=size) + head -= size; + buffer[2] = head; + ++buffer[1]; +} + +static inline void ringbuffer_blocking_push(uint8_t *buffer, uint8_t value) +{ + const volatile uint8_t *fill = buffer+1; + while(*fill>=buffer[0]) ; + ringbuffer_push(buffer, value); +} + +static inline uint8_t ringbuffer_pop(uint8_t *buffer) +{ + const uint8_t size = buffer[0]; + uint8_t tail = buffer[3]; + uint8_t value = buffer[4+tail++]; + if(tail>=size) + tail -= size; + buffer[3] = tail; + --buffer[1]; + return value; +} + +static inline uint8_t rinbuffer_blocking_pop(uint8_t *buffer) +{ + const volatile uint8_t *fill = buffer+1; + while(*fill==0) ; + return ringbuffer_pop(buffer); +} + +#endif