__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