I'm reading through this online book on x86 and I'm curious about an implementation detail in their example code for implementing a spin lock. In the example, they use a xchg to set a memory location to 0 rather than a mov and I'm trying to understand why that choice was made.
In the spin lock example there is a function, spinUnlock which puts a 0 in the memory location [sLock]. [sLock] is set to 0 if the lock is free and 1 when it is aquired. The spinUnlock function sets [sLock] to 0 freeing the lock. The code follows:
spinUnlock:
push ebp
mov ebp, esp
mov eax, 0
xchg eax, [sLock]
pop ebp
ret
Why use mov eax, 0; xchg eax, [sLock] to set [sLock] to 0 rather than mov [sLock], 0? The eax register is not used for anything after the calls to spinUnlock. I know that xchg will lock the memory location, but if mov is already atomic then a lock is unnecessary.
Only the author can say why the choice was made.
A single
mov dword [sLock],0would work fine; and anxchg eax, [sLock](which has an impliedlock) is likely to be more expensive (for both performance and code size).All of the example's code is awful (e.g. no
pausein thespinLockroutine where it should be used despite havingpausein places where it shouldn't be used at all); and their choice of example isn't good either.Note: using spinlocks in user-space is "almost never" sane because the OS may do a task switch after you acquire a lock but before you release it, causing all other tasks to waste a massive amount of CPU time spinning with no hope of acquiring the lock.