Subject: Re: Atomic ops API
To: Johnny Billquist <bqt@softjar.se>
From: Bang Jun-Young <junyoung@netbsd.org>
List: tech-kern
Date: 03/16/2007 00:43:00
On 3/15/07, Johnny Billquist <bqt@softjar.se> wrote:
> Bang Jun-Young wrote:
> > On 3/15/07, Johnny Billquist <bqt@softjar.se> wrote:
> >
> >> The whole point is that is must return correct values, otherwise it is
> >> unusable. So therefore, between the readout of the old value, and the
> >> writing of a new value, no other processor can be allowed to modify the
> >> *target, or it is unusable and meaningless. Ie. it really needs to be
> >> atomic all the way, and not just a single step of it. :-)
> >
> >
> > That's what CMPXCHG instruction does as part of atomic_cas().
>
> This is getting silly.
> Jason's idea was to have a compare_and_store() since a
> compare_and_swap() can be complex on some machines. You then said that
> it's not, since a compare_and_swap() can be implemented easily this way:
>
>  >> 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. :-)
>
> I then pointed out that your function will not work the way you'd
> expect, and that it wouldn't be useful. The return value is pretty much
> useless, since it will not tell you if the compare_and_store_32()
> actually did store something or not.
>
> Your answer to that is that an instruction such as CMPXCHG solves your
> problem. The thing is, if you do have a CMPXCHG, your suggested
> implementation above is needless, since the CMPXCHG instruction will do
> the deal for you.
> And if you don't have a CMPXCHG instruction, then the above C code will
> not do the work. You'll need to have a mutex around the whole construct!
> And yes, a C function can implement an atomic operation. I'm not saying
> that the C function itself would be atomic, and there is no need for
> that. But the operation it is defined to perform can be done atomically.
> Either by using an underlying instruction that the processor
> architecture guarantees will be atomic, or by protecting the code by a
> mutex.
>
> This should be pretty obvious. :-)

I'd say nobody would write an atomic op in pure C. :-) The first one was just
a conceptual implementation with an if omitted (yes, it was a mistake). The
difference is, Jason undestood what I tried to explain, and you didn't, maybe
because you didn't read Solaris sources before.

See Solaris atomic.c if you're more interested in this subject. There are lots
of atomic operations written in pure C just to make lint happy. They
are actually
not atomic and don't work, but are enough to explain what each operation tries
to do. Don't complain them why those functions don't actually work. :-)

Jun-Young