Search code examples
assemblyx86spinlock

mov vs xchg in spin lock implementatoin


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.


Solution

  • Only the author can say why the choice was made.

    A single mov dword [sLock],0 would work fine; and an xchg eax, [sLock] (which has an implied lock) is likely to be more expensive (for both performance and code size).

    All of the example's code is awful (e.g. no pause in the spinLock routine where it should be used despite having pause in 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.