From: David F. <fa...@kd...> - 2025-08-06 11:04:41
|
On Monday, 4 August 2025 16:24:38 David Yonge-Mallo wrote: > Running helgrind naturally produces the output that there is a data race in > "flag" between the two threads. > > If the flag is replaced by an atomic, helgrind produces a clean report. Yes, thait seems correct to me. > According to my understanding, this is a false negative. There is still no > "happens-before" relationship between the read in thread #1 and the write > in thread #2. The program can terminate with copyOfFlag being either true > or false, which means the race condition still exists. Well, using an atomic turns the data race into what I would call a "semantic" race (if anyone knows the official term for this, I'm interested). There are many things you can do in a multithreaded program which follows the rules of the C/C++ memory model (such as using an atomic in this case) and which still leads to semantic races. This is one of them. > According to my colleague, helgrind by design only cares that a read and a > write on the same memory does not happen at the same time, and making the > bool atomic fixes this. It's not really about "at the same time", it could be much later, but as long as there's no synchronization mechanism between the two things, it's a data race. (Think of an ARM CPU with two cores, each with their own cache, the caches aren't necessarily synchronized so you can be reading the wrong value forever even "after" a write, if the read happens on the other core and nothing syncs the caches). > The indeterminacy of the value of copyOfFlag is a > separate issue, which helgrind cannot detect as it is not within the scope > of its design. That's right. > I claimed that helgrind does not understand atomic variables. My colleague > disbelieved this and made the counterargument that if a mutex is used to > guard access to flag (instead of making it atomic), it also produces a > clean report, and since helgrind undoubtedly understands mutexes, it must > mean that the data race is fixed. Yes, the "data race" (as defined by the C/C++ memory model) is technically fixed, even though a "semantic" race is still happening. Imagine a program where one thread increments an atomic int repeatedly and another thread decrements an atomic int repeatedly. Or an int protected by a mutex, same thing. It's all perfectly legal from the C/C++ standards' point of view, there's no data race that leads to undefined behaviour at the compiler/ CPU level. And yet the whole idea of such a program leads to indeterminism, you have no idea what the int's value will be after 10 seconds, because it all depends on thread scheduling by the OS. There are many more factors for indeterminism than data races ;-) -- David Faure, fa...@kd..., http://www.davidfaure.fr |