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.