Richard Henderson <r...@twiddle.net> writes: > On 04/15/2016 07:23 AM, Alex Bennée wrote: >> +#define atomic_bool_cmpxchg(ptr, old, new) \ >> + ({ \ >> + typeof(*ptr) _old = (old), _new = (new); \ >> + bool r; \ >> + r = __atomic_compare_exchange(ptr, &_old, &_new, false, \ >> + __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); \ >> + r; \ >> + }) > > How are you thinking this will be used? If a loop like > > do { > old = atomic_read (ptr); > new = f(old); > } while (!atomic_bool_cmpxchg(ptr, old, new)); > > then it's usually helpful to use a weak compare_exchange (s/false/true/ > above). > This will produce one loop for ll/sc architectures instead of two.
I used it to make Fred's STREX code a little neater: if (len == 1 << size) { oldval = (uint8_t)env->exclusive_val; result = atomic_bool_cmpxchg(p, oldval, (uint8_t)newval); } address_space_unmap(cs->as, p, len, true, result ? len : 0); Instead of: if (len == 1 << size) { oldval = (uint8_t)env->exclusive_val; result = (atomic_cmpxchg(p, oldval, (uint8_t)newval) == oldval); } address_space_unmap(cs->as, p, len, true, result ? len : 0); But now I'm wondering if there is a race in there. I'll have to look closer. > > > r~ -- Alex Bennée