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

Reply via email to