I am getting into a race condition with 2 threads while using atomic CAS.
std::atomic<int> turn(0);
int free = 0;
void Work(int pid){
while(true){
if(turn.compare_exchange_strong(free, pid)){
std::cout << "Thread " << pid << " is running on core " << sched_getcpu() << std::endl;
turn.store(free);
}
}
}
int main(){
std::thread t1 = std::thread(Work, 1);
std::thread t2 = std::thread(Work, 2);
t1.join();
t2.join();
}
Can someone please help me understand why the above code is not thread-safe?
In your code, you have:
std::atomic<int> turn(0);
int free = 0;
and then in Work():
if(turn.compare_exchange_strong(free, pid)) { … }
Both threads are using the same variable free as the expected value and, due to its modification by the compare_exchange_strong operation upon failure, the value of free may no longer be what you intended (which was 0).
Each thread should use its own local variable as the expected value.
void Work(int pid) {
while(true) {
int expected = 0; // local copy of free
if(turn.compare_exchange_strong(expected, pid)){
std::cout << "Thread " << pid << " is running on core " << sched_getcpu() << std::endl;
turn.store(0);
}
}
}