/** * @file * * FIFO Buffers * ============ * * Simple FIRST IN FIRST OUT * * Requires * -------- * * Requires kballoc/kbfree - block allocation * * Thread Safety * ------------- * * **NOTE** : If you have more than one producer and one consumer * you will have to do some locking! * * ringbuffer_init() and ringbuffer_free() can be logically called only * once anyway (for each ringbuffer). * * The structure is believed to be thread-safe as long as you have * ONLY _ONE_ single producer AND _ONE_ single consumer PER ringbuffer. * * With one Consumer and one Producer: * * The Consumer can use: * - ringbuffer_has() - will not give false positives. * - ringbuffer_empty() - will not give false negatives. * - ringbuffer_get() - acceseses only the head-pointer. * * The Producer can use: * - ringbuffer_not_full() - will not give false positives * - ringbuffer_full() - will not give false negatives. * - ringbuffer_put() - accesses only the tail-pointer. * * Todo * ---- * provide soemthing to read large blocks faster. * */ #ifndef RINGBUFFER_H #define RINGBUFFER_H #include #include /** Ringbuffer sturcutre */ typedef struct ringbuffer_struct { uint32_t size; // size in bytes uint32_t head; // current head idx uint32_t tail; // current tail idx uint8_t *data; // the data itself }ringbuffer; /** Create a new fifo/ringbuffer of given size (in blocks) */ ringbuffer ringbuffer_init(uint32_t blocks); /** Deallocate buffer */ void ringbuffer_free(ringbuffer *f); /** Put one _byte_ into the buffer. */ bool ringbuffer_put(ringbuffer*,uint8_t); /** Get a single _byte_ from the buffer. */ uint8_t ringbuffer_get(ringbuffer*); /** Check if the buffer is not empty */ bool ringbuffer_has(ringbuffer*); /** Check if the buffer is empty */ bool ringbuffer_empty(ringbuffer*); /** Check if the buffer is full */ bool ringbuffer_full(ringbuffer* f); /** Check if the buffer is not full */ bool ringbuffer_not_full(ringbuffer* f); #endif