just wondered if any more-experienced-than-i devs might comment on this. written in c for c (obviously). i realize it's not portable outside of GNU GCC (regarding the GCC atomic builtin funcs __sync_***). meant for a single reader thread and a single writer thread. comments regarding thread safety very much welcome. thanks in advance.
james. #include "rng_buf.h" /* only prototypes the public functions and typedefs the struct */ #include <stdlib.h> #include <string.h> #include "debug.h" struct _RingBuffer { size_t count; void** buf; void** bufend; void** volatile w; void** volatile r; }; RngBuf* rng_buf_new(size_t count) { size_t sz = 1; RngBuf* mb = malloc(sizeof(RngBuf)); if (!mb) { return 0; } for (sz = 1; sz < count; sz <<= 1) ; mb->buf = calloc(sz, sizeof(void*)); if (!mb->buf) { free(mb); return 0; } mb->count = sz; mb->bufend = mb->buf + mb->count - 1; mb->w = mb->buf; mb->r = mb->buf; return mb; } void rng_buf_free(RngBuf* mb) { free(mb->buf); free(mb); } size_t rng_buf_write(RngBuf* mb, const void* data) { if (__sync_bool_compare_and_swap(mb->w, 0, data)) { if (!(__sync_bool_compare_and_swap(&mb->w, mb->bufend, mb->buf))) __sync_add_and_fetch(&mb->w, sizeof(void*)); return (size_t)1; } return (size_t)0; } void* rng_buf_read(RngBuf* mb) { void* data; if ((data = __sync_fetch_and_and(mb->r, 0))) { if (!__sync_bool_compare_and_swap(&mb->r, mb->bufend, mb->buf)) __sync_add_and_fetch(&mb->r, sizeof(void*)); return data; } return NULL; } void rng_buf_reset(RngBuf* mb) { /* needs work */ mb->r = mb->w = mb->buf; } _______________________________________________ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org http://lists.linuxaudio.org/listinfo/linux-audio-dev