Here's one proof it is not atomic in a particular implementation (gcc),
As you can see (?), gcc generates code that
- loads the value from memory to a register
- increments the content of the register
- saves the register back to memory.
That's very far from being atomic.
$ cat t.c
volatile int a;
void func(void)
{
a++;
}
[19:51:52 0 ~] $ gcc -O2 -c t.c
[19:51:55 0 ~] $ objdump -d t.o
t.o: file format elf32-i386
Disassembly of section .text:
00000000 :
0: a1 00 00 00 00 mov 0x0,%eax
5: 83 c0 01 add $0x1,%eax
8: a3 00 00 00 00 mov %eax,0x0
d: c3 ret
Don't be fooled by the 0x0 in the mov instruction, there's room for 4 bytes there, and the linker will fill in the resulting memory address for a there when this object file is linked.