On Tue, 2007-08-07 at 15:38 -0600, Chris Friesen wrote: > Chris Snook wrote: > > > That's why we define atomic_read like so: > > > > #define atomic_read(v) ((v)->counter) > > > > This avoids the aliasing problem, because the compiler must de-reference > > the pointer every time, which requires a memory fetch. > > Can you guarantee that the pointer dereference cannot be optimised away > on any architecture? Without other restrictions, a suficiently > intelligent optimiser could notice that the address of v doesn't change > in the loop and the destination is never written within the loop, so the > read could be hoisted out of the loop. > > Even now, powerpc (as an example) defines atomic_t as: > > typedef struct { volatile int counter; } atomic_t > > > That volatile is there precisely to force the compiler to dereference it > every single time.
I just tried this with GCC 4.2 on x86_64 because I was curious. struct counter_t { volatile int counter; } test; struct counter_t *tptr = &test; int main() { int i; tptr->counter = 0; i = 0; while(tptr->counter < 100) { i++; } return 0; } $ gcc -O3 -S t.c a snippet of t.s: main: .LFB2: movq tptr(%rip), %rdx movl $0, (%rdx) .p2align 4,,7 .L2: movl (%rdx), %eax cmpl $99, %eax jle .L2 Now with the volatile removed: main: .LFB2: movq tptr(%rip), %rax movl $0, (%rax) .L2: jmp .L2 If the compiler can see it clearly, it will optimize out the load without the volatile. -- Zan Lynx <[EMAIL PROTECTED]>
signature.asc
Description: This is a digitally signed message part