Boost logo

Boost Users :

Subject: [Boost-users] [lockfree] overwriting push?
From: Rich E (reakinator_at_[hidden])
Date: 2013-05-10 13:16:58


I'm using boost::lockfree::spsc_queue in an audio graph to allow audio
input samples written from one thread to be read from another. This
currently looks like:

#include <boost/lockfree/spsc_queue.hpp>
class RingBuffer {
public:
RingBuffer() : mLockFreeQueue( 0 ) {}

RingBuffer( size_t size ) : mLockFreeQueue( size + 1 ), mSize( size ) {}
~RingBuffer() {}

//! pushes to buffer, overwriting oldest samples
void write( const float *samples, size_t count ) {
if( count > mSize ) {
count = mSize;
}
size_t numPushed = mLockFreeQueue.push( samples, count );
if( count > numPushed ) {
size_t numLeft = count - numPushed;
// ???: is there a more efficient way to overwrite?
float old;
for( int i = 0; i < numLeft; i++ ) {
mLockFreeQueue.pop( old );
}
numPushed = mLockFreeQueue.push( &samples[numPushed], numLeft );
assert( numPushed == numLeft );
}
}

size_t read( float *samples, size_t count ) {
if( count > mSize ) {
count = mSize;
}
return mLockFreeQueue.pop( samples, count );
}

private:
boost::lockfree::spsc_queue<float> mLockFreeQueue;
size_t mSize;
};

If there is not enough space in the write call, I sequentially pop off
elements until there is enough. Is there a better way to do this? It
seems like there should be a mechanism for just moving the read head
forward (atomically) without reading anything, but then I am not sure I
completely understand the implications of that on the lockfree model. I'm
also not 100% sure this is adhering to the lockfree model, so please inform
me if/how it isn't if you know.

Thank you for your time,
Rich



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net