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

James Morris jwm.art.net at gmail.com
Mon Jul 11 20:32:08 UTC 2011


On 11 July 2011 20:19, Olivier Guilyardi <list at samalyse.com> wrote:

> Good catch... Multi-core ARM devices are actually arriving massively. With
> Android, there's the Motorola Atrix, the Samsung Galaxy S II, etc..
>

What about my toaster? :-P

I've ended up going back to Fons's pragmatism. If
non-blocking/lock-free programming is so impossibly difficult,
requiring intimate hardware knowledge of numerous different
architectures then there's only one solution available to people like
me, and that's to code for AMD64/Intel and use the existing ringbuffer
implementations.

I'd be interested though if my usage of  __sync_bool_compare_and_swap
and  __sync_fetch_and_and improves the ring buffer at all? I like the
fact the implementation I'm using is so simple. Trouble is, using the
GCC builtins instead of volatile slows it down. Guess that means it's
duff.

James.

----------------8<-------------------------

#include "rng_buf.h"

#include <stdlib.h>
#include <string.h>


struct _RingBuffer
{
    void** buf;
    void** bufend;

    void** w;
    void** 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->bufend = mb->buf + sz - 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))
    {
        mb->w = (mb->w == mb->bufend) ? mb->buf : mb->w + 1;
        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)))
    {
        mb->r = (mb->r == mb->bufend) ? mb->buf : mb->r + 1;
        return data;
    }

    return NULL;
}


----------------8<-------------------------



More information about the Linux-audio-dev mailing list