Skip to content

Instantly share code, notes, and snippets.

@fbstj
Created February 15, 2013 09:11
Show Gist options
  • Save fbstj/4959298 to your computer and use it in GitHub Desktop.
Save fbstj/4959298 to your computer and use it in GitHub Desktop.
A ring-buffer generation utility
/*
simple ring buffer
*/
#ifndef RING_BUFFER_H_
#define RING_BUFFER_H_
enum E_RING_BUFFERS { e_RING_OK = 0, e_RING_EMPTY, e_RING_FULL, e_RING_ERROR };
#define T_RING(T, tag, len)\
struct tag { T buffer[len]; unsigned int head, tail; };\
static inline void RING_##tag##_init(struct tag *const o) { o->head = o->tail = 0; }\
const unsigned int RING_##tag##_length = len;\
static inline unsigned int RING_##tag##_count(struct tag *const o) { return (len + o->head - o->tail) % len; }\
static inline unsigned int RING_####tag##_space(struct tag *const o) { return len - RING_##tag##_count(o); }\
static inline enum E_RING_BUFFERS RING_##tag##_add(struct tag *const o, T *const item)\
{\
if ((o->head > len) | (o->tail > len)) return e_RING_ERROR;\
if (RING_##tag##_count(o) == len) return e_RING_FULL;\
memcpy(o->buffer + o->tail, item, sizeof(T));\
o->head = (o->head < len) ? o->head + 1 : 0;\
return e_RING_OK;\
}\
static inline enum E_RING_BUFFERS RING_##tag##_get(struct tag *const o, T *const item)\
{\
if ((o->head > len) | (o->tail > len)) return e_RING_ERROR;\
if (RING_##tag##_count(o) == 0) return e_RING_EMPTY;\
memcpy(item, &o->buffer + o->tail, sizeof(T));\
o->tail = (o->tail < len) ? o->tail + 1 : 0;\
return e_RING_OK;\
}
#endif // RING_BUFFER_H_
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment