[LAD] a *simple* ring buffer, comments pls?

From: James Morris <jwm.art.net@email-addr-hidden>
Date: Thu Jul 07 2011 - 15:10:13 EEST

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@email-addr-hidden
http://lists.linuxaudio.org/listinfo/linux-audio-dev
Received on Thu Jul 7 20:15:07 2011

This archive was generated by hypermail 2.1.8 : Thu Jul 07 2011 - 20:15:07 EEST