Search code examples
c++multithreadingrace-conditionlock-freethread-sanitizer

Is Thread Sanitizer expected to be able to correctly analyze lock-free code?


Background motivation: I have some code that uses a lock-free algorithm to share audio data to/from a CoreAudio callback (only because CoreAudio callbacks-threads are real-time and therefore aren't allowed to lock mutexes). This code seems to work fine, but if I run it under Clang's Thread Sanitizer tool, some race-condition diagnostics are reported.

My question is: to what extent is Thread Sanitizer expected to be able to correctly reason about race conditions in the context of lock-free code? i.e. can it reliably tell the difference between a buggy lock-free algorithm that has a genuine race condition and a correctly-written lock-free algorithm that does not, or is it expected that the Thread Sanitizer will just say "hey, you wrote to this data structure in thread A and later read from it in thread B, and no mutex-locking was ever observed, so I'm going to print a diagnostic about that"?

If Thread Sanitizer is able to correctly analyze lock-free algorithms, any related information about how it does that, and/or how the lock-free algorithm might be tuned/annotated to make Thread Sanitizer's diagnoses more accurate would be appreciated.


Solution

  • As far as I know thread sanitizer should, setting aside bugs, not produce false positives with the caveats that

    1. C++ exceptions are not supported,
    2. fences are not properly supported,
    3. all code, including the standard library, needs to be compiled with TSAN instrumentation, and
    4. for synchronization, directly or indirectly, only pthreads primitives and compiler built-in atomics may be used.

    Of course, it can only detect data races and similar UB situations and only in execution paths taken. It cannot generally recognize race conditions that result in unintended behavior or evaluate whether a data structure is thread-safe.