Is there any acausal behavior with dependency loops in the C ++ Depleted Memory Model?
Suppose x
u y
are atomic integers, initialized to 0.
Now Thread A runs the following code:
if (x.load(memory_order_relaxed) == 1) {
y.store(1, memory_order_relaxed);
}
and Thread B runs this code:
if (y.load(memory_order_relaxed) == 1) {
x.store(1, memory_order_relaxed);
}
Is it possible in C ++ to achieve a situation where (x == 1 and y == 1)
? If possible, why?
I saw this claim at https://people.mpi-sws.org/~viktor/slides/2014-07-ec2.pdf (the dependency loop section).
source to share
Often with these questions it is possible to answer the question without understanding what atomic variables are, imagine all the possible scenarios.
What is an atomic operation? This is an operation that cannot be broken. This is either done or not done.
With this in mind, let's consider all possible scenarios.
- Can any of these cases go into an if condition? Not. Since both are variables
0
and nothing will turn them into1
.
It sounds trivial, but all your possibilities. The more important question is, why should x or y become 1
in the first place? Based on what you provided. There is no reason.
EDIT:
My only comment on this presentation that you linked is that this is simply wrong. To prove it, I used this program and the cases never went into if conditions. Anyone reading this please confirm what I am saying because I may be wrong. I ran this program for a few minutes and nothing happened (gcc (Debian 6.2.1-5) 6.2.1 20161124)
.
#include <iostream>
#include <atomic>
#include <thread>
std::atomic_int x,y;
void call1()
{
while(true)
{
if(x.load(std::memory_order_relaxed) == 1)
{
std::cout<<"I'm in!"<<std::endl;
y.store(1, std::memory_order_relaxed);
}
}
}
void call2()
{
while(true)
{
if(y.load(std::memory_order_relaxed) == 1)
{
std::cout<<"I'm also in!"<<std::endl;
x.store(1, std::memory_order_relaxed);
}
}
}
int main()
{
x.store(0);
y.store(0);
std::thread t1(call1);
std::thread t2(call2);
t1.join();
t2.join();
return 0;
}
source to share