__sync_lock_test_and_set on ARM

Phil Endecott spam_from_gcc_help_2@chezphil.org
Thu Sep 13 14:30:00 GMT 2007


Andrew Haley wrote:
> Phil Endecott writes:
>  > Andrew Haley wrote:
>  > > this stuff really should be done by the compiler. 
>  > 
>  > Yes.  I've filed a bug asking for a __sync_lock_test_and_set builtin:
>  > 
>  > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33413
>
> Surer, but the problem is that for most of the things we want to do
> (lightweight locks, for example) __sync_lock_test_and_set() doesn't
> really do what we need: we need compare_and_swap().

There are several factors, e.g.:
(a) Does your system's threading model allow a high-priority thread 
that is in a spin lock to eventually be interrupted?
(b) Can you allow a sentinel value in your atomic type?
(c) Do you expect to hold locks for extended periods, or just for a few 
instructions at a time?

In my case I'm implementing reference counts, and a solution using just 
swap is possible.  Calling the kernel-helper thing to get 
compare-and-swap would add a lot of unnecessary overhead.

BTW you can do lightweight locks using just swap, something like this:

int mutex;  // 1=locked, 0=unlocked

void lock() {
   int x=1;
   do {
     swap(mutex,x);   // if mutex was unlocked, it is now locked and x==0
                      // if mutex was locked, it is still locked and x==1
   } while (x==1)
}

void unlock() {
   mutex=0;
}

This requires that a thread that is in the spin loop will eventually be 
pre-empted by the thread that holds the lock, and is only efficient if 
the critical sections are short.  If these conditions hold, it needs 
far fewer instructions that the compare-and-swap kernel-helper version.


Regards,

Phil.






More information about the Gcc-help mailing list