I have the following code that runs fine on Intel processors but produces weird data on ARM processors.
I suspect that this is a synchronisation problem.
Basically I have a producer thread calling setLiveData(...)
periodically and a consumer thread calling getLiveData(...)
periodically as well.
.h file
class DataHandler{
public:
...
private:
LiveDataValue lastValues_;
bool lastValuesValid;
};
.cpp file
bool DataHandler::getLiveData(LiveDataValue *val)
{
if(this->lastValuesValid){
*val = this->lastValues_;
return true;
}else
return false;
}
void DataHandler::setLiveData(LiveDataValue val)
{
this->lastValuesValid = false;
this->lastValues = val;
this->lastValuesValid = true;
}
Just by reading the code, I think that I need to make sure that setLiveData
is atomic in the sense that a consumer thread can't call getLiveData(...)
while a producer thread is in the middle of setLiveData(...)
I've found this answer and tried to used it fixing the code:
.h file
class DataHandler{
public:
...
private:
LiveDataValue lastValues_;
std::atomic<bool> lastValuesValid;
};
.cpp file
bool DataHandler::getLiveData(LiveDataValue *val)
{
while (!this->lastValuesValid.load(std::memory_order_acquire))
{
std::this_thread::yield();
}
if(this->lastValuesValid){
*val = this->lastValues_;
return true;
}else
return false;
}
void DataHandler::setLiveData(LiveDataValue val)
{
this->lastValuesValid_.store(false, std::memory_order_release);
this->lastValues = val;
this->lastValuesValid_.store(true, std::memory_order_release);
}
My problem is that I never exit the while loop in getLiveData called by the reader thread. Why is that?
EDIT : LiveDataValue is a complex union typedef, not detailed here.
Aucun commentaire:
Enregistrer un commentaire