You have the right idea, but your asm is broken:
cmpxchg cannot work with the direct operand, it is registered only.
lock not a valid prefix for mov . mov to a aligned address is atomic on x86, so you don't need lock anyway.
It has been a while since I used the AT & T syntax, I hope I remembered everything:
spin_lock: xorl %ecx, %ecx incl %ecx spin_lock_retry: xorl %eax, %eax lock; cmpxchgl %ecx, (lock_addr) jnz spin_lock_retry ret spin_unlock: movl $0 (lock_addr) ret
Note that GCC has atomic built-in functions, so you do not need to use the built-in asm to accomplish this:
void spin_lock(int *p) { while(!__sync_bool_compare_and_swap(p, 0, 1)); } void spin_unlock(int volatile *p) { asm volatile ("");
As stated below in God, locked instructions carry costs: everyone you use must clear your cache and lock your system memory bus, which can be quite expensive if you have enough processors. Even without the use of many processors, it is still easy and worth optimizing:
void spin_lock(int volatile *p) { while(!__sync_bool_compare_and_swap(p, 0, 1)) { while(*p) _mm_pause(); } }
The pause instruction is vital for performance on HyperThreading processors when you have code that rotates this way - it allows the second thread to execute while the first thread is spinning. On CPUs that do not support pause , it is treated as nop .
Cory Nelson Aug 04 2018-11-11T00: 00Z
source share