Andrew Haley wrote:
Andrew Haley writes:
> Phil Endecott writes:
> > Dear Experts,
> >
> > I believe that ARM's swap instruction can be used to implement the
> > __sync_lock_test_and_set builtin, yet as far as I can see it is not
> > implemented. Can anyone please confirm if (a) it is implemented but
> > I'm doing something wrong, or (b) there's some reason why it can't be
> > done? FWIW here is some asm that I am currently using for this:
> >
> > asm volatile ("swp\t%0, %1, [%2]"
> > :"=r" (oldval)
> > :"r" (newval),
> > "r" (&mem)
> > :"memory");
>
> Looks fine to me.
I forgot: SWP is deprecated on ARM. Use LDREX and STREX instead.
See http://lkml.org/lkml/2006/12/6/180
Hi Andrew,
Thanks for your replies.
Yes, some ARMs have LDREX and STREX, but currently these still provide
SWP. I'm coding for an XScale which only has SWP.
But I don't believe that gcc implements __sync builtins that expand to
the LDREX or STREX instructions either, does it?
This raises another issue, which is whether there is any way for code
to determine which of the atomic builtins are provided, i.e. I'd like
to write:
#if HAS__sync_lock_test_and_set
.. locking code using __sync_lock_test_and_set
#elseif HAS__sync_something_else
.. locking code using builtins that expand to LDREX and STREX
#else
#warn "no atomic ops, falling back to pthread mutex"
...
#endif
Any thoughts? My current asm is working OK, but if it could be
re-written to use the builtins, and if it were possible to test at
compile time which builtins are actually provided on that platform,
then it would perhaps become more portable.
Regards,
Phil.