Darryl Gove's blog
Atomic operations in Solaris 10
Atomic operations are available in Solaris 10 through the
% more atom.c #includevolatile unsigned int test; void main() { test=0; for (int i=0; i<10000; i++){atomic_add_int(&test,i);} } % cc -O atom.c % a.out
Here's the disassembly for atomic_add_int from lib:
atomic_add_int() 2dc18: ld [%o0], %o2 2dc1c: add %o2, %o1, %o3 <---| 2dc20: cas [%o0] , %o2, %o3 | 2dc24: cmp %o2, %o3 | 2dc28: bne,a,pn %icc, 0x2dc1c ----| 2dc2c: mov %o3, %o2 ----| [delay slot] 2dc30: retl 2dc34: add %o2, %o1, %o0
The idea of atomic functions is that they complete without anything else being able to change the variable during the operation - as if the operation were a single step. They are exteremely useful when data is shared between threads
The basic idea, as can be seen in the add code, is that the variable is loaded, the add is performed, the value stored back (using the atomic instruction 'cas' - compare and swap). Then the result is checked to see whether it worked or not. If it didn't work the operation is repeated.
The cas instruction performs the test that if the value held at [%o0] is equal to the value %o2, then replace it with the value %o3. %o3 returns the value that was in [%o0] when the operation was tried.
The instruction in the delay slot of the branch gets executed together with the branch instruction.
Posted at 01:36PM Jan 11, 2007 by Darryl Gove in Sun |


