spin_lock forgets to clobber memory and other smp fixes [was Re: [patch] waitqueue optimization, 2.4.0-test7]

Jamie Lokier egcs@tantalophile.demon.co.uk
Thu Sep 7 09:39:00 GMT 2000

Andrea Arcangeli wrote:
> >> 	int a = *p;
> >> 	__asm__ __volatile__("" : :);
> >> 	a = *p;
> >> 
> >> (to do two explicit reads)
> >
> >Sorry, that does just one read, kgcc (old stable gcc) and also with
> >gcc-2.96.  Type aliasing on/off makes no difference to the number of reads.
> I wrote the above not just as a complete testecase, but just to mean what
> the case I was talking about. You made int a a local variable and the
> thing you noticed is an otimization that the compiler is allowed to do
> regardless of the "memory" clobber too (`int a' have to be at least extern
> otherwise the compiler understands the first read can go away).

Interestingly enough, the local variable case is one where "memory" does
make a difference.  Without "memory":

        movl    p, %eax
        movl    (%eax), %eax

With "memory":

        movl    p, %eax
        movl    (%eax), %eax

> Try to add "memory" as clobber to the above testcase and nothing will
> change. (that's what I meant in my previous email saying that even w/o
> "memory" things got compiled right at least in my simple testcases)

As you can see from above, there are cases where

   local_var = shared->mumble;
   // ...
   spin_lock (&spinlock);
   local_var = shared->mumble;

requires a "memory" clobber, otherwise the second read, which is in a
critical region, won't be emitted by the compiler.

-- Jamie

ps. There is a _clobber_ for memory, but no way to say "this asm _reads_
arbitrary memory".  __volatile__ may be filling that role though.

More information about the Gcc mailing list