Richard Henderson <[email protected]> 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