Our processors are allowed to reorder the instruction in order to gain some performance benefits, but this may cause some strange behaviour. I'm trying to reproduce one of this issues on the base of this article.
This is my code:
int a,b;
int r1,r2;
mutex m1,m2;
void th1()
{
for(;;)
{
m1.lock();
a=1;
asm volatile("" ::: "memory");
r1=b;
m1.unlock();
}
}
void th2()
{
for(;;)
{
m2.lock();
b=1;
asm volatile("" ::: "memory");
r2=a;
m2.unlock();
}
}
int main()
{
int cnt{0};
thread thread1{th1};
thread thread2{th2};
thread1.detach();
thread2.detach();
for(int i=0;i<10000;i++)
{
m1.lock();
m2.lock();
a=b=0;
m1.unlock();
m2.unlock();
if(r1==0&&r2==0)
{
++cnt;
}
}
cout<<cnt<<" CPU reorders happened!\n";
}
I use the mutexes to be sure that the 'main' thread will not modify a nor b when th1 or th2 are doing their jobs, the output of the execution change all the time, it may be 0, it may be 10000 or a casual number between 0 and 10000.
There's something about this code that makes me little unconfortable, i'm not sure whether it really reproduce the CPU reordering phenomen.
From the code looks like the only way r1 and r2 may be 0 in the 'if' is because of th1 and th2 set them to the value from 'a' and 'b', which in the context of th1 and th2 cannot be 0 due to the lock mechanism, the only way those variables are 0 is because of the instruction reordering, this this correct?
Thanks