Phil Endecott wrote:
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
The proper symbol to test would be something like:
__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 or
__GCC_HAVE_SYNC_LOCK_TEST_AND_SET_4 they are automatically set by GCC
when the builtin functions are available.
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,
My personal preference would be to use the GCC builtins when possible.
If they are not generating proper code for your target, file a bug
report so they can be fixed.
David Daney