> } while (__c11_atomic_compare_exchange_weak( > addr, &oldval, newval, memory_order_seq_cst, memory_order_relaxed));Actually, I think this condition is inverted. Should be "while (!_c11...". Sorry about that. Tim.
As a followup: could I do a "strong" cmpxchg and leave out the loop? (According to http://en.cppreference.com/w/c/atomic/atomic_compare_exchange that is preferable when possible). Here is (my understanding of) the equivalent LLVM: void emitAtomicFPAdd(Value *ptr, Value *incr) { LoadInst *oldval = builder->CreateLoad(ptr); Value *newval = builder->CreateAdd(oldval, incr); Instruction *cmpxchg builder->CreateAtomicCmpXchg(ptr, oldval, newval, AtomicOrdering::SequentiallyConsistent, AtomicOrdering::SequentiallyConsistent); } Quoting Tim Northover <t.p.northover at gmail.com>:>> } while (__c11_atomic_compare_exchange_weak( >> addr, &oldval, newval, memory_order_seq_cst, memory_order_relaxed)); > > Actually, I think this condition is inverted. Should be "while > (!_c11...". Sorry about that. > > Tim.
On 26 April 2015 at 06:31, Tyler Denniston <tyler at csail.mit.edu> wrote:> As a followup: could I do a "strong" cmpxchg and leave out the loop? > (According to http://en.cppreference.com/w/c/atomic/atomic_compare_exchange > that is preferable when possible).No. You could do a strong compare and exchange, leaving the loop in; but a weak one is better here. If you leave the loop out entirely then if someone else modifies addr between your first load and the cmpxchg attempt then you won't change it at all: the cmpxchg will fail and that'll be the end of it. The difference is that the weak exchange is allowed to fail even if the comparison means it should have stored. This makes no difference on x86, but most RISC targets actually implement a strong cmpxchg as a loop (carrying on until the failure is a real comparison failure rather than the spurious ones that architecture can generate): 1. Load addr. 2. Compare against expected value, abort if it's different. 3. Try to store new value, failing if anyone else touched addr (even just to read) between the 1 and now. 4. If the store failed goto 1. Using weak cmpxchg skips the final looping step, which is more efficient for your purposes because you're just going to have to go around again in your own loop anyway. Cheers. Tim.