On 11 July 2011 20:19, Olivier Guilyardi <l...@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<------------------------- _______________________________________________ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org http://lists.linuxaudio.org/listinfo/linux-audio-dev