[parisc-linux] Re: [parisc-linux-cvs] linux grundler

James Bottomley James.Bottomley@steeleye.com
09 Feb 2003 08:55:33 -0600


On Sat, 2003-02-08 at 20:03, Matthew Wilcox wrote:
> I think it's even worse than that.  What stops gcc reordering:
> 
> typedef struct {
>         spinlock_t lock;
>         volatile int counter;
> } rwlock_t;
> 
> static  __inline__ void _raw_read_lock(rwlock_t *rw)
> {
>         while (__ldcw (&(x)->lock) == 0) \
>                 while (((x)->lock) == 0) ; } while (0)
>         rw->counter++;
>         do { (x)->lock = 1; } while(0)
> }
> 
> to:
> 
>         while (__ldcw (&(x)->lock) == 0) \
>                 while (((x)->lock) == 0) ; } while (0)
>         do { (x)->lock = 1; } while(0)
>         rw->counter++;

Compilers themselves have fairly strong reordering rules.  For instance,
do { } while() blocks cannot be reordered like your example (that's why
the kernel uses do { } while(0); as a compiler reordering barrier.

You can if you prefer use the barrier() macro, which prevents the
compiler from reordering statements around it.

Of course, the processor can still reorder what the compiler doesn't as
part of its speculation and optimisation (that's what mb(), rmb() and
wmb() are all about).

James