On 10/18/2011 06:07 PM, Jakub Jelinek wrote:
On Tue, Oct 18, 2011 at 06:03:16PM -0400, Andrew MacLeod wrote:
Here's the last of the missing intrinsics. compare_exchange is
slightly different than the others since it doesn't map directly to
an rtl pattern. Its format is :
bool __atomic_compare_exchange (T* mem, T* expected, T desired,
bool weak, memory_order success, memory_order failure)
note that the expected parameter is a pointer as well. In the case
where false is returned, the value of expected is updated.
I think the __sync_* way here was much better (two intrinsics instead of
one, one bool-ish and one returning val). With mandating T*expected
you force it to be addressable, probably until expansion time at which point
it will be just forced into memory, which is highly undesirable.
Its impossible to implement a weak compare and swap unless you return
both parameters in one operation.
the compare_exchange matches the atomic interface for c++, and if we
can't resolve it with a lock free instruction sequence, we have to leave
an external call with this format to a library, so I that why I provide
this built-in.
Neither rth nor I like the addressable parameter, so thats why I left
the rtl pattern for weak and strong compare and swap without that
addressable argument, and let this builtin generate wrapper code around it.
You could provide an __atomic version of the bool and val routines with
memory model.... we toyed with making the compare_and_swap return both
values so we could implement a weak version, but getting 2 return values
is not pretty. It could be done with 2 separate built-ins that relate
to each other, but thats not great either.
we may think of a more brilliant way later to do it under the covers,
but at the moment, this gets us the external interface we're looking for.
Andrew