I am trying to find a way to block Free or Non-blocking to create a ring buffer for one consumer / one consumer, which will overwrite the oldest data in the buffer. I read a lot of non-blocking algorithms that work when you "return false" if the buffer is full, i.e. do not add; but I canβt even find a pseudo-code that talks about how to do this when you need to overwrite the oldest data.
I use GCC 4.1.2 (restriction on work, I canβt update the version ...), and I have Boost libraries, and in the past I made my own Atomic <T>, which follows pretty close to the upcomming specification (its not perfect, but it is thread safe and does what I need).
When I thought about this, I decided that using these atoms should really take care of the problem. some rude psuedo code regarding what I thought:
template< typename T , unsigned int Size> class RingBuffer { private: Atomic<unsigned int> readIndex; Atomic<unsigned int> writeIndex; enum Capacity { size = Size }; T* buf; unsigned int getNextIndex(unsigned int i) { return (i + 1 ) % size; } public: RingBuffer() {
As far as I can tell, there are no deadlock situations here, so we are safe from this (if my implementation above is incorrect even on its pseudo-code, constructive criticism is always appreciated). However, the BIG state I can find is:
suggests that the buffer is full. i.e. writeIndex +1 = readIndex; (1) occurs in the same way as consumption. and true (4) is wrong, so we move on to reading from buffer (5), and readIndex is one (therefore, in fact, the space in buffer (2) advances readIndex AGAIN, thus LOSING the value.
Basically, his classic writer problem is to change the reader, causing a race condition. Without actually blocking the entire list every time I access it, I cannot figure out how to prevent this. What am I missing?
c ++ c nonblocking circular-buffer
Nik
source share