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

From: James Morris <jwm.art.net@email-addr-hidden>
Date: Mon Jul 11 2011 - 23:32:08 EEST

On 11 July 2011 20:19, Olivier Guilyardi <list@email-addr-hidden> 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<-------------------------
_______________________________________________
Linux-audio-dev mailing list
Linux-audio-dev@email-addr-hidden
http://lists.linuxaudio.org/listinfo/linux-audio-dev
Received on Tue Jul 12 00:15:04 2011

This archive was generated by hypermail 2.1.8 : Tue Jul 12 2011 - 00:15:04 EEST