I have a consumer thread that must never lock nor allocate memory, and a producer thread that can. I want to implement a two place circular buffer to be able to provide data to the consumer thread from the producer, with the bound that whenever no new data is available to consume, the consumer just re-uses the already available data.
This is what I've come up with for now:
bool newDataAvailable = false;
bool bufferEmpty = true;
foo* currentData = new foo();
foo* newData = new foo();
void consumer() {
while(true) {
currentData->doSomething();
if(newDataAvailable) {
foo* tmp = currentData;
// Objects are swapped so the old one can be reused without additional allocations
currentData = newData;
newData = tmp;
newDataAvailable = false;
bufferEmpty = true;
}
}
}
void producer() {
while(true) {
while(!bufferEmpty) { wait(); }
newData->init();
bufferEmpty = false;
newDataAvailable = true;
}
}
Is this naive implementation ok? I know reading and writing to variables can be non-atomic, so I should use an atomic storage, but those can cause locks. Is the use of atomic storage needed here?
Also, I'd like to eliminate the active wait in the producer, and I thought I could use a std::condition_variable
, but they require the use of mutexes and I cannot afford them.