Messages in this thread | | | Subject | Re: why are some atomic_t's not volatile, while most are? | From | Zan Lynx <> | Date | Tue, 07 Aug 2007 16:32:57 -0600 |
| |
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 <zlynx@acm.org> [unhandled content-type:application/pgp-signature] | |