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
#include
#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
LINUX® is a registered trademark of Linus Torvalds in the USA and other countries.
Linuxaudio.org logo copyright Thorsten Wilms © 2006.
Hosting provided by the Virginia Tech Department of Music and DISIS.