http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50583
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |RESOLVED CC| |jakub at gcc dot gnu.org Resolution| |INVALID --- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> 2011-09-30 18:49:29 UTC --- (In reply to comment #3) > movl (%rdi), %eax > .L2: > movl %eax, %edx > andl $7, %edx > lock cmpxchgl %edx, (%rdi) > jne .L2 > movl %edx, %eax > It is > > { > tmp = *ptr; > do > { > tmp1 = tmp OP value; > } > while (__sync_val_compare_and_swap (ptr, tmp, tmp1) != tmp); > return tmp1; > } > > If *ptr is changed between load and cmpxchg, we get an infinite loop. No, you aren't translating the asm correctly back into C. It is tmp = *ptr; do tmp1 = tmp OP value; tmp2 = tmp; while ((tmp = __sync_val_compare_and_swap (ptr, tmp2, tmp1) != tmp2); return tmp1; because cmpxchgl instruction loads the *ptr value from memory into %eax if the instruction has been unsuccessful. So, tmp is loaded with the new value for the next iteration.