Reduce the cost of the synthetic TSan races.

On the read side avoid writing to memory via volatile. The volatile access will generate its own tsan checks because it is touching memory.
On the write side also avoid the volatile access by unconditionally writing to the memory. The address used for the tsan validation is dedicated for it so it doesn't matter if we write arbitrary values to it.

PiperOrigin-RevId: 559841351
pull/13667/head
Protobuf Team Bot 2 years ago committed by Copybara-Service
parent 879a51285a
commit 066465c978
  1. 19
      src/google/protobuf/port_def.inc

@ -838,16 +838,17 @@ static_assert(PROTOBUF_ABSL_MIN(20230125, 3),
#ifdef PROTOBUF_TSAN
// TODO(b/285620714): it would be preferable to use __tsan_external_read/
// __tsan_external_write, but they can cause dlopen issues.
#define PROTOBUF_TSAN_READ(addr) \
do { \
volatile char protobuf_tsan_dummy = *reinterpret_cast<const char *>(addr); \
(void)protobuf_tsan_dummy; \
#define PROTOBUF_TSAN_READ(addr) \
do { \
char protobuf_tsan_dummy = *reinterpret_cast<const char *>(addr); \
asm volatile("" : "+r"(protobuf_tsan_dummy)); \
} while (0)
#define PROTOBUF_TSAN_WRITE(addr) \
do { \
char protobuf_tsan_zero = 0; \
asm volatile("" : "+m"(protobuf_tsan_zero)); \
*reinterpret_cast<char *>(addr) += protobuf_tsan_zero; \
// We currently use a dedicated member for TSan checking so the value of this
// member is not important. We can unconditionally write to it without affecting
// correctness of the rest of the class.
#define PROTOBUF_TSAN_WRITE(addr) \
do { \
*reinterpret_cast<char *>(addr) = 0; \
} while (0)
#else // PROTOBUF_TSAN
#define PROTOBUF_TSAN_READ(addr)

Loading…
Cancel
Save