Subject: Re: Atomic ops API
To: Johnny Billquist <bqt@softjar.se>
From: Bang Jun-Young <junyoung@netbsd.org>
List: tech-kern
Date: 03/15/2007 21:38:05
On 3/15/07, Johnny Billquist <bqt@softjar.se> wrote:
> Bang Jun-Young wrote:
> > On 3/15/07, Johnny Billquist <bqt@softjar.se> wrote:
> >
> >> Isn't the whole point of a function called "atomic_compare_and_store"
> >> that it would be atomic? Otherwise I would say that it was misnamed.
> >> So, it should not be possible for *target to be modified withing the
> >> atomic_compare_and_store by some other entity, or the function isn't
> >> atomic.
> >>
> >
> > The atomic function means "a function that performs an atomic
> > operation", not
> > "a funtion that is atomic itself."
>
> Then I think the name is stupid, and furthermore, that means that the
> return value of the function is meaningless. It will not tell you
> anything. Instead you will always have to check after the operation
> wether it performed the swap or not. But that in itself will not answer
> the question wether the swap was performed or not either, since the
> value that you were supposed to write in case of a match might be the
> value that was already there.
The return value _is_ very important, indeed. It's used to determine if
*target has been overwritten by another thread before the cas operation was
peformed. If it has, you should load the new value to *target and call
atomic_cas() again. This time if no other thread overwrites *target, the
call succeeds (and returns with the expected 'old' value).
>
> So in essence, your implementation of atomic_compare_and_swap() or
> atomic_compare_and_store becomes a maybe_store(), without you being able
> to tell wether you did the store or not, and without being able to know
> what the value was before the operation.
Actually, it's just not mine. :-) FreeBSD, Solaris, Windows, Linux, and all the
other OS'es making use of fine-grained locking have the almost same atomic
cas functions on i386 architecture.
> What would be the point of this function?
A lot. :-)
For another example, atomic_cas() is used to implement spinlock:
acquire_lock(lock)
{
while (1)
if (atomic_cas(lock, 0, 1) == 0)
break;
/*
* Lock is acquired.
*/
}
Now isn't it clear why the return value is important? :-)
Jun-Young