[tsan] Treat non-barrier OSAtomic* functions as barriers to avoid false positives
The non-barrier versions of OSAtomic* functions are semantically mo_relaxed, but the two variants (e.g. OSAtomicAdd32 and OSAtomicAdd32Barrier) are actually aliases of each other, and we cannot have different interceptors for them, because they're actually the same function. Thus, we have to stay conservative and treat the non-barrier versions as mo_acq_rel. Differential Revision: http://reviews.llvm.org/D21733 llvm-svn: 273890
This commit is contained in:
parent
7d1ebed0c5
commit
ca2668d038
|
@ -27,6 +27,14 @@ typedef long long_t; // NOLINT
|
|||
|
||||
namespace __tsan {
|
||||
|
||||
// The non-barrier versions of OSAtomic* functions are semantically mo_relaxed,
|
||||
// but the two variants (e.g. OSAtomicAdd32 and OSAtomicAdd32Barrier) are
|
||||
// actually aliases of each other, and we cannot have different interceptors for
|
||||
// them, because they're actually the same function. Thus, we have to stay
|
||||
// conservative and treat the non-barrier versions as mo_acq_rel.
|
||||
static const morder kMacOrderBarrier = mo_acq_rel;
|
||||
static const morder kMacOrderNonBarrier = mo_acq_rel;
|
||||
|
||||
#define OSATOMIC_INTERCEPTOR(return_t, t, tsan_t, f, tsan_atomic_f, mo) \
|
||||
TSAN_INTERCEPTOR(return_t, f, t x, volatile t *ptr) { \
|
||||
SCOPED_TSAN_INTERCEPTOR(f, x, ptr); \
|
||||
|
@ -53,23 +61,24 @@ namespace __tsan {
|
|||
}
|
||||
|
||||
#define OSATOMIC_INTERCEPTORS_ARITHMETIC(f, tsan_atomic_f, m) \
|
||||
m(int32_t, int32_t, a32, f##32, __tsan_atomic32_##tsan_atomic_f, mo_relaxed) \
|
||||
m(int32_t, int32_t, a32, f##32, __tsan_atomic32_##tsan_atomic_f, \
|
||||
kMacOrderNonBarrier) \
|
||||
m(int32_t, int32_t, a32, f##32##Barrier, __tsan_atomic32_##tsan_atomic_f, \
|
||||
mo_acq_rel) \
|
||||
kMacOrderBarrier) \
|
||||
m(int64_t, int64_t, a64, f##64, __tsan_atomic64_##tsan_atomic_f, \
|
||||
mo_relaxed) \
|
||||
kMacOrderNonBarrier) \
|
||||
m(int64_t, int64_t, a64, f##64##Barrier, __tsan_atomic64_##tsan_atomic_f, \
|
||||
mo_acq_rel)
|
||||
kMacOrderBarrier)
|
||||
|
||||
#define OSATOMIC_INTERCEPTORS_BITWISE(f, tsan_atomic_f, m, m_orig) \
|
||||
m(int32_t, uint32_t, a32, f##32, __tsan_atomic32_##tsan_atomic_f, \
|
||||
mo_relaxed) \
|
||||
kMacOrderNonBarrier) \
|
||||
m(int32_t, uint32_t, a32, f##32##Barrier, __tsan_atomic32_##tsan_atomic_f, \
|
||||
mo_acq_rel) \
|
||||
kMacOrderBarrier) \
|
||||
m_orig(int32_t, uint32_t, a32, f##32##Orig, __tsan_atomic32_##tsan_atomic_f, \
|
||||
mo_relaxed) \
|
||||
kMacOrderNonBarrier) \
|
||||
m_orig(int32_t, uint32_t, a32, f##32##OrigBarrier, \
|
||||
__tsan_atomic32_##tsan_atomic_f, mo_acq_rel)
|
||||
__tsan_atomic32_##tsan_atomic_f, kMacOrderBarrier)
|
||||
|
||||
OSATOMIC_INTERCEPTORS_ARITHMETIC(OSAtomicAdd, fetch_add,
|
||||
OSATOMIC_INTERCEPTOR_PLUS_X)
|
||||
|
@ -88,16 +97,16 @@ OSATOMIC_INTERCEPTORS_BITWISE(OSAtomicXor, fetch_xor,
|
|||
TSAN_INTERCEPTOR(bool, f, t old_value, t new_value, t volatile *ptr) { \
|
||||
SCOPED_TSAN_INTERCEPTOR(f, old_value, new_value, ptr); \
|
||||
return tsan_atomic_f##_compare_exchange_strong( \
|
||||
(tsan_t *)ptr, (tsan_t *)&old_value, (tsan_t)new_value, mo_relaxed, \
|
||||
mo_relaxed); \
|
||||
(tsan_t *)ptr, (tsan_t *)&old_value, (tsan_t)new_value, \
|
||||
kMacOrderNonBarrier, kMacOrderNonBarrier); \
|
||||
} \
|
||||
\
|
||||
TSAN_INTERCEPTOR(bool, f##Barrier, t old_value, t new_value, \
|
||||
t volatile *ptr) { \
|
||||
SCOPED_TSAN_INTERCEPTOR(f##Barrier, old_value, new_value, ptr); \
|
||||
return tsan_atomic_f##_compare_exchange_strong( \
|
||||
(tsan_t *)ptr, (tsan_t *)&old_value, (tsan_t)new_value, mo_acq_rel, \
|
||||
mo_relaxed); \
|
||||
(tsan_t *)ptr, (tsan_t *)&old_value, (tsan_t)new_value, \
|
||||
kMacOrderBarrier, kMacOrderNonBarrier); \
|
||||
}
|
||||
|
||||
OSATOMIC_INTERCEPTORS_CAS(OSAtomicCompareAndSwapInt, __tsan_atomic32, a32, int)
|
||||
|
@ -120,9 +129,9 @@ OSATOMIC_INTERCEPTORS_CAS(OSAtomicCompareAndSwap64, __tsan_atomic64, a64,
|
|||
return orig_byte & mask; \
|
||||
}
|
||||
|
||||
#define OSATOMIC_INTERCEPTORS_BITOP(f, op, m) \
|
||||
OSATOMIC_INTERCEPTOR_BITOP(f, op, m, mo_relaxed) \
|
||||
OSATOMIC_INTERCEPTOR_BITOP(f##Barrier, op, m, mo_acq_rel)
|
||||
#define OSATOMIC_INTERCEPTORS_BITOP(f, op, m) \
|
||||
OSATOMIC_INTERCEPTOR_BITOP(f, op, m, kMacOrderNonBarrier) \
|
||||
OSATOMIC_INTERCEPTOR_BITOP(f##Barrier, op, m, kMacOrderBarrier)
|
||||
|
||||
OSATOMIC_INTERCEPTORS_BITOP(OSAtomicTestAndSet, __tsan_atomic8_fetch_or,
|
||||
0x80u >> bit_index)
|
||||
|
|
Loading…
Reference in New Issue