[Circular Buffer] Partial thread-safety

It would be very helpful if this container provided lock-free thread-safe implementation of concurrent reads and writes by two threads (producer-consumer), as such function is often needed where ring buffers are used. A prime example of that being receiving audio from a callback (possibly a signal handler), where the callback must not be blocked in any circumstances (meaning that it cannot wait for a lock). As this is a rather common use case, the realtime audio processing framework JACK actually implements such lock-free ring buffer: http://jackit.sourceforge.net/cgi-bin/lxr/http/source/libjack/ringbuffer.c Is there any reason why Boost.circular_buffer should not also implement this kind of thread-safety?

----- Original Message ----- From: "Lasse Kärkkäinen" <tronic+67zr@trn.iki.fi> To: <boost@lists.boost.org> Sent: Wednesday, November 26, 2008 9:45 AM Subject: [boost] [Circular Buffer] Partial thread-safety
It would be very helpful if this container provided lock-free thread-safe implementation of concurrent reads and writes by two threads (producer-consumer), as such function is often needed where ring buffers are used. A prime example of that being receiving audio from a callback (possibly a signal handler), where the callback must not be blocked in any circumstances (meaning that it cannot wait for a lock).
As this is a rather common use case, the realtime audio processing framework JACK actually implements such lock-free ring buffer:
http://jackit.sourceforge.net/cgi-bin/lxr/http/source/libjack/ringbuffer.c
Is there any reason why Boost.circular_buffer should not also implement this kind of thread-safety?
Hi, thanks for pointing this issue. As you say this is a very common case, one producer, one consumer. The idea could also be useful for the ThreadPool library. Where is the magic? Can you point to some documentation or how to use it? Thanks, Vicente

Where is the magic? Can you point to some documentation or how to use it?
It seems to make the assumption that volatile variable reads and writes are atomic. This, among with careful organization of those operations, allows safe concurrent access. C++03 does not define any atomic operations, but in practice these seem to be atomic on all implementations with int-sized and smaller variables. Documentation for the JACK ring buffer (also links to the header code): http://jackaudio.org/files/docs/html/ringbuffer_8h.html

Lasse Kärkkäinen wrote:
Where is the magic? Can you point to some documentation or how to use it?
It seems to make the assumption that volatile variable reads and writes are atomic. This, among with careful organization of those operations, allows safe concurrent access.
This sort of assumption looks wrong. volatile should only instruct the compiler not to optimize the variable (e.g. in a register). BR, Dmitry

Where is the magic? Can you point to some documentation or how to use it?
It seems to make the assumption that volatile variable reads and writes are atomic. This, among with careful organization of those operations, allows safe concurrent access.
This sort of assumption looks wrong. volatile should only instruct the compiler not to optimize the variable (e.g. in a register).
the ringbuffer is known not to be smp-safe without memory barriers ... btw, i have a boost-style lockfree fifo class [1], with support for multiple concurrent producers/consumers ... i haven't found the time to make it ready for a submission, yet ... cheers, tim [1] http://tim.klingt.org/git?p=boost_lockfree.git -- tim@klingt.org http://tim.klingt.org Art is either a complaint or do something else John Cage quoting Jasper Johns

One of the many excellent tech articles at Insomniac Games is a useful introduction to optimising a one producer/one consumer multithreaded message queue. Many of the issues are analogous to problems here. http://www.insomniacgames.com/tech/articles/0807/multithreading_optimization...
participants (5)
-
Dmitry Goncharov
-
Lasse Kärkkäinen
-
Paul Baxter
-
Tim Blechmann
-
vicente.botet