Subject: Re: Atomic ops API
To: Jason Thorpe <thorpej@shagadelic.org>
From: Johnny Billquist <bqt@softjar.se>
List: tech-kern
Date: 03/14/2007 13:18:20
Jason Thorpe wrote:
>
> On Mar 13, 2007, at 5:42 PM, Bang Jun-Young wrote:
>
>> On 3/13/07, Jason Thorpe <thorpej@shagadelic.org> wrote:
>>
>>> The API is borrowed from Solaris. There is one major difference,
>>> however. Solaris defines "cas" as COMPARE-AND-SWAP, returning the
>>> previous value of the memory cell. I have defined it as COMPARE-AND-
>>> STORE, returning true if the ops succeeds, or false otherwise. The
>>> reason for this is because some platforms will have extreme difficulty
>>> implementing COMPARE-AND-SWAP, whereas COMPARE-AND-STORE is somewhat
>>> easier for these platforms.
>>
>> uint32_t
>> atomic_compare_and_swap_32(volatile uint32_t *target, uint32_t cmp,
>> uint32_t new)
>> {
>> uint32_t old = *target;
>> (void) atomic_compare_and_store_32(target, cmp, new);
>> return old;
>> }
>>
>> I think atomic_compare_and_swap_*() might not be so difficult to
>> implement or
>> expensive as you expected. :-)
>
> You're missing the memory barrier before fetching the old target.
> Extra memory barriers are expensive.
Memory barrier or not, I wouldn't expect the above code to work anyway.
The value of the target could very well change between the read and the
actual store.
So you could actually have a situation where old == cmp, but the store
didn't take place, since the value of target changed before the
atomic_compare_and_store. Thus, you might think that you did a write,
but in reality you didn't.
The value of *target can change between the read and the atomic modify.
Or am I missing something?
Johnny