Skip to content

Instantly share code, notes, and snippets.

@temoto
Created January 28, 2016 08:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save temoto/cb0cef313bfa03b4df3f to your computer and use it in GitHub Desktop.
Save temoto/cb0cef313bfa03b4df3f to your computer and use it in GitHub Desktop.
Ring buffer in C, push to tail, pop from head, single size define <=256
#include <stdbool.h> // bool, required
#include <stdio.h> // printf, only for debug
#include <stdlib.h> // uint8_t, required
#include <string.h> // memset, required
#define RING_BUFFER_SIZE 4
#if RING_BUFFER_SIZE > 256
#error "RING_BUFFER_SIZE must be <=256"
#endif
typedef struct {
uint8_t data[RING_BUFFER_SIZE];
uint8_t head;
uint8_t tail;
bool over;
} RingBuffer_t;
void Ring_Init(RingBuffer_t* const b) {
memset(b->data, 0, RING_BUFFER_SIZE);
b->head = 0;
b->tail = 0;
b->over = false;
}
bool Ring_PushTail(RingBuffer_t* const b, uint8_t value) {
if (b->over && (b->tail == b->head)) {
printf("ring push(%c) ERR over\n", value);
return false;
}
uint8_t next = (b->tail + 1) % RING_BUFFER_SIZE;
if (next == b->head) {
b->over = true;
}
b->data[b->tail] = value;
b->tail = next;
printf("ring push(%c) head=%d tail=%d next=%d over=%d\n", value, b->head,
b->tail, next, b->over);
return true;
}
bool Ring_PopHead(RingBuffer_t* const b, uint8_t* const out) {
if (!b->over && (b->tail == b->head)) {
printf("ring pop ERR empty head=%d tail=%d over=%d\n", b->head, b->tail,
b->over);
return false;
}
uint8_t next = (b->head + 1) % RING_BUFFER_SIZE;
*out = b->data[b->head];
// b->data[b->head] = 0;
b->head = next;
b->over = false;
printf("ring pop out=%c head=%d tail=%d over=%d\n", *out, b->head,
b->tail, b->over);
return true;
}
void Ring_Debug(RingBuffer_t const* const b) {
printf("ring debug data=[%c%c%c%c] head=%d tail=%d over=%d content=[",
b->data[0]!=0?b->data[0]:'.',
b->data[1]!=0?b->data[1]:'.',
b->data[2]!=0?b->data[2]:'.',
b->data[3]!=0?b->data[3]:'.',
b->head, b->tail, b->over);
uint8_t h = b->head, t = b->tail, n = t - h;
if (b->over && (h == t)) {
n = RING_BUFFER_SIZE;
} else if (h > t) {
n = RING_BUFFER_SIZE - h + t;
}
for (uint8_t i = 0; i < n; i++) {
uint8_t j = (h + i) % RING_BUFFER_SIZE;
printf("%c", b->data[j]);
}
printf("]\n");
}
int main() {
RingBuffer_t rb;
uint8_t v;
Ring_Init(&rb);
Ring_Debug(&rb);
Ring_PushTail(&rb, '1');
Ring_Debug(&rb);
Ring_PushTail(&rb, '2');
Ring_Debug(&rb);
Ring_PushTail(&rb, 't');
Ring_Debug(&rb);
Ring_PopHead(&rb, &v);
Ring_Debug(&rb);
Ring_PushTail(&rb, '3');
Ring_Debug(&rb);
Ring_PushTail(&rb, '4');
Ring_Debug(&rb);
Ring_PushTail(&rb, 'e');
Ring_Debug(&rb);
Ring_PopHead(&rb, &v);
Ring_Debug(&rb);
Ring_PopHead(&rb, &v);
Ring_Debug(&rb);
Ring_PopHead(&rb, &v);
Ring_Debug(&rb);
Ring_PopHead(&rb, &v);
Ring_Debug(&rb);
Ring_PopHead(&rb, &v);
Ring_Debug(&rb);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment