On 24 Mar 2016, at 15:10, Dmitry Vyukov <dvy...@google.com> wrote:+thread-sanitizer mailing list
On Thu, Mar 24, 2016 at 2:50 PM, Kuba Brecka <jbr...@apple.com> wrote:Hi Dmitry!
I’ve just seen some false positives from TSan due to missing support of some
C++11 atomics, namely fences and atomic_compare_exchange’s “failure memory
ordering”. In compiler-rt, there is a FIXME for fences:
static void AtomicFence(ThreadState *thr, uptr pc, morder mo) {
// FIXME(dvyukov): not implemented.
__sync_synchronize();
}
and a comment about fmo in CAS:
static bool AtomicCAS(ThreadState *thr, uptr pc,
volatile T *a, T *c, T v, morder mo, morder fmo) {
(void)fmo; // Unused because llvm does not pass it yet.
... // rest of code doesn’t use ‘fmo’ at all.
}
Are these two things “just not implemented yet” or is there something hard
about adding support for these? Are fences and CAS+fmo used so rarely that
you don’t see false positives due to them? Why isn’t the fmo parameter
correctly passed to AtomicCAS()?
Hi Kuba,
CAS failure order should not lead to false positives, because we use
success order which must be not weaker than failure order.
The comment looks like it is from ancient times when tsan was not part
of llvm repository. So I guess we now can use fmo.
On Thu, Mar 24, 2016 at 11:05 PM, <rjmc...@gmail.com> wrote:
> On Thursday, March 24, 2016 at 9:41:20 AM UTC-7, Kuba Brecka wrote:
>>
>>
>> > On 24 Mar 2016, at 15:49, Dmitry Vyukov <dvy...@google.com> wrote:
>> >
>> > 20.7.2.5/32
>> > Requires: failure shall not be memory_order_release,
>> > memory_order_acq_rel, or stronger than success.
>>
>> Sure. I’m just curious about the definition of “stronger” here.
>
>
> Chandler, JF Bastien, Tim Northover, and I discussed this on LLVM IRC, and
> the result was:
>
> 1. The standard doesn't clearly specify what "stronger" means. However, we
> all agreed that the sensible interpretation is that memory orderings are a
> lattice, not a totally ordered set, and the relationships are:
>
> relaxed < (release | (consume < acquire)) < acq_rel < seq_cst
>
> 2. Given that two orderings aren't necessarily comparable, it isn't clear
> whether the requirement is (failure <= success) or !(success < failure).
20.7.2.5/32 explicitly rules out memory_order_release and
memory_order_acq_rel, so I don't see any ambiguity.
> However, it is extremely likely that this will be resolved as merely a
> deficiency in the current wording. In particular, it is clear that there
> are architectures where some incomparable pairs can be compiled much more
> efficiently than the nearest comparable pair; most notably, on AArch64
> (release, consume) can be much more efficient than (acq_rel, consume). So I
> would strongly encourage you to handle these cases correctly.
This is not necessary possible to implement portably. Consider
Itanium-style atomic operations, where you supply ordering constraint
to the instruction itself (st.rel, ld.acq). Unless you pass both
failure and success memory orders to the instruction, the instruction
won't be able to omit acquire part in success case.
And on compiler
level you obviously don't know whether CAS will fail or not, so you
have to promote (release, acquire) to (acq_rel, acquire) anyway.
It seems to me that what you want is memory_order_con_rel. Why not? It
is useful in other cases (e.g. when you exchange a pointer with
another pointer). (the fact that no existing compiler supports consume
aside)
But we still need to wait for the standard committee to legalize this
and for LLVM support.
std::atomic_compare_exchange_strong_explicit(&ptr, &expected, value, std::memory_order_release, std::memory_order_acquire);
By looking at the IR generated by the above call, it seems to me that the fail order is lost somewhere:%1 = cmpxchg i64* ... release monotonic
--
You received this message because you are subscribed to the Google Groups "thread-sanitizer" group.
To unsubscribe from this group and stop receiving emails from it, send an email to thread-sanitiz...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Hi JF!If what I posted in 2016 is still the case...std::atomic_compare_exchange_strong_explicit(&ptr, &expected, value, std::memory_order_release, std::memory_order_acquire);By looking at the IR generated by the above call, it seems to me that the fail order is lost somewhere:%1 = cmpxchg i64* ... release monotonic...then I believe there is no bug in TSan, but rather a bug in LLVM or Clang which mis-generates the IR for the above-mentioned pair of memory orderings in a CAS. Can you file a bug on LLVM?
Kuba
To unsubscribe from this group and stop receiving emails from it, send an email to thread-sanitizer+unsub...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to a topic in the Google Groups "thread-sanitizer" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/thread-sanitizer/bTOVyLAo8p4/unsubscribe.
To unsubscribe from this group and all its topics, send an email to thread-sanitizer+unsubscribe@googlegroups.com.
template<typename T>
static bool AtomicCAS(ThreadState *thr, uptr pc,volatile T *a, T *c, T v, morder mo, morder fmo) {(void)fmo; // Unused because llvm does not pass it yet.
...
To unsubscribe from this group and stop receiving emails from it, send an email to thread-sanitiz...@googlegroups.com.
You're right:template<typename T>static bool AtomicCAS(ThreadState *thr, uptr pc,volatile T *a, T *c, T v, morder mo, morder fmo) {(void)fmo; // Unused because llvm does not pass it yet.
...
Kuba
Kuba
To unsubscribe from this group and stop receiving emails from it, send an email to thread-sanitiz...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to a topic in the Google Groups "thread-sanitizer" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/thread-sanitizer/bTOVyLAo8p4/unsubscribe.
To unsubscribe from this group and all its topics, send an email to thread-sanitiz...@googlegroups.com.