0

the following code acquire a mutex using lock_cmpxchg on an index of an array, then two threads write and read to the same index, but still thread sanitizer say there is a data race. how can I tell him the fact there is a lock between the threads because it seem it does not detect it.

 aquire_mutex(bool* lock_ptr)
 {
   retval = _lock_cmpxchg_8bit(0, 1, lock_ptr); //lock_cmpxchg implemented in inline assembly
   return (retval == 0) ? 1: 0;
 }

foo()
{
  if (aquire_mutex(global_lock[index])!= 1)
  {
    return error;
  }
  uint x = array[index];
  ...
  array[index] = random_value;
}

the flow is: a lot of threads are running with different indexes or the same index, the only data race appear if two threads are with the same index, but there is a lock for it. but thread sanitizer warn that there is a read in line uint x = array[index]; by thread 1 and there is a write in line array[index] = random_value ; Im not sure why it does detect data race, Thanks for the help!!

Moshe Levy
  • 174
  • 9
  • Have you tried turning on some of the [runtime options](https://github.com/google/sanitizers/wiki/ThreadSanitizerFlags) that are disabled by default? I have no idea if it helps but I'd try running with: `TSAN_OPTIONS="force_seq_cst_atomics=1" ./your_program` – Ted Lyngmo Aug 30 '21 at 06:39
  • @TedLyngmo Thanks, where should i write this line? because I get TSAN_OPTIONS=history_size=7 force_seq_cst_atomics=1: Command not found. – Moshe Levy Aug 30 '21 at 07:08
  • It depends on your shell. What I suggested works in `bash`. If you use a different shell, try setting this environment variable first and then run the command separately. – Ted Lyngmo Aug 30 '21 at 07:17
  • 1
    Depending on how `_lock_cmpxchg_8bit` is implemented, it might be opaque to the compiler. You might want to show its source, and possibly rewrite it to use compiler intrinsics. – Hasturkun Aug 30 '21 at 12:52

1 Answers1

0

As Hasturkun suggested, the problem was that Thread Sanitizer know nothing about the inline assembly hence he does not detect it as a lock, I used instead __sync_bool_compare_and_swap built GCC intrinsic, and now thread sanitizer does not report any false negative!!

according to Dmitry Vyukov https://github.com/google/sanitizers/issues/1443

Moshe Levy
  • 174
  • 9