// can handle one buffer for a start. // later make it reentrant and manage multiple buffers! // todo: syncing access to buffer. #define FOOLOS_MODULE_NAME "ringbuffer" #include "lib/bool/bool.h" #include "lib/logger/log.h" #include "kernel/spinlock.h" #define RINGBUFFER_SIZE 10 static volatile int size=RINGBUFFER_SIZE; static volatile int front=RINGBUFFER_SIZE-1; static volatile int back=RINGBUFFER_SIZE-1; static volatile char buf[RINGBUFFER_SIZE]; bool ringbuffer_put(char c) { log(FOOLOS_MODULE_NAME,FOOLOS_LOG_FINE,"put wants lock)"); lock_spin(3); log(FOOLOS_MODULE_NAME,FOOLOS_LOG_FINE,"locked by put)"); if((back-1+size)%size==front) { lock_release(3); log(FOOLOS_MODULE_NAME,FOOLOS_LOG_FINE,"unlocked by put)"); return false; } buf[back]=c; log(FOOLOS_MODULE_NAME,FOOLOS_LOG_FINE,"put %d %d (%c)", back, front,c); back--; back+=size; back%=size; lock_release(3); log(FOOLOS_MODULE_NAME,FOOLOS_LOG_FINE,"unlocked by put)"); return true; } bool ringbuffer_get(char *c) { log(FOOLOS_MODULE_NAME,FOOLOS_LOG_FINE,"get wants lock)"); lock_spin(3); log(FOOLOS_MODULE_NAME,FOOLOS_LOG_FINE,"locked by get)"); if(front==back) { lock_release(3); log(FOOLOS_MODULE_NAME,FOOLOS_LOG_FINE,"unlocked by get)"); return false; } *c=buf[front]; log(FOOLOS_MODULE_NAME,FOOLOS_LOG_FINE,"get %d %d (%c)", back, front,*c); front--; front+=size; front%=size; lock_release(3); log(FOOLOS_MODULE_NAME,FOOLOS_LOG_FINE,"unlocked by get)"); return true; }