// 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 "ringbuffer.h" #include "kernel/x86.h" #include "lib/logger/log.h" #include "kernel/spinlock.h" #define RINGBUFFER_SIZE 10 static int size=RINGBUFFER_SIZE; static volatile int front=RINGBUFFER_SIZE-1; static volatile int back=RINGBUFFER_SIZE-1; static volatile char buf[RINGBUFFER_SIZE]; static spinlock sl=9; bool ringbuffer_put(char c) { x86_int_disable(); log(FOOLOS_MODULE_NAME,FOOLOS_LOG_FINE,"put wants lock"); lock_spin(sl); log(FOOLOS_MODULE_NAME,FOOLOS_LOG_FINE,"locked by put"); if((back-1+size)%size==front) { lock_release(sl); log(FOOLOS_MODULE_NAME,FOOLOS_LOG_FINE,"unlocked by put"); x86_int_enable(); 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(sl); log(FOOLOS_MODULE_NAME,FOOLOS_LOG_FINE,"unlocked by put"); x86_int_enable(); return true; } bool ringbuffer_get(char *c) { x86_int_disable(); log(FOOLOS_MODULE_NAME,FOOLOS_LOG_FINE,"get wants lock"); lock_spin(sl); log(FOOLOS_MODULE_NAME,FOOLOS_LOG_FINE,"locked by get"); if(front==back) { lock_release(sl); log(FOOLOS_MODULE_NAME,FOOLOS_LOG_FINE,"unlocked by get"); x86_int_enable(); *c='_'; 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(sl); log(FOOLOS_MODULE_NAME,FOOLOS_LOG_FINE,"unlocked by get"); x86_int_enable(); return true; }