Razican
Razican

Reputation: 727

Unit tests fail only in ARM

I am working on a multithreaded program for a Raspberry Pi, and I have noticed that our current code runs perfectly in my computer and in the computers of other colleges, but it fails when running on ARM.

We are using C++11 for our project, and this is the output in our computer:

............ Success! Test run complete. 12 tests run. 12 succeeded.

But when we try to run it on ARM, as you can see here: https://travis-ci.org/OpenStratos/server/builds/49297710

It says the following:

.... No output has been received in the last 10 minutes, this potentially indicates a stalled build or something wrong with the build itself.

After some debugging, I have understood that the issue comes to this code: https://github.com/OpenStratos/server/blob/feature/temperature/serial/Serial.cpp#L91

this->open = false;
while( ! this->stopped);

And there is another thread doing the opposite:

while(this->open)
{
    // Do stuff
}
this->stopped = true;

The first code is called when I need to stop the thread, and the double flag is ussed for the thread to be able to update the current object even if it's stopping. Both variables are of type std::atomic_bool, but it seems that in the while ( ! this->stopped); it does not check for it, ant it supposes a while (true);.

Is this the case? how can it be solved? why does it work differently on my x86_64 processor than on the ARM?

Thanks in advance.

Upvotes: 0

Views: 104

Answers (2)

Razican
Razican

Reputation: 727

Finally the issue was that the environment I was creating in Travis.ci was not working properly. In real ARM hardware works properly.

Upvotes: 0

MSalters
MSalters

Reputation: 180145

The core guarantee made by std::atomic<T> is that you can always read a value. Consistency is not necessarily guaranteed.

Now, in this case you're relying on .operator bool which is equivalent to .load(memory_order_seq_cst) and operator=(x) which is .store(x, memory_order_seq_cst). This should give you a sequential consistent memory order.

The order you're observing on ARM appears sequentially consistent to me. The fast that you're not yet seeing stopped == true is OK. There's no time limit on that. The compiler cannot swap the memory operation with another memory operation, but it may indefinitely delay it.

The main question is why this thread should be stopped at all. If there was any real, observable work done in the loop body of that thread, that loop body could not be reordered relative to stopped==true check.

Upvotes: 1

Related Questions