Take a look here
The basic idea is load the lock value and immediately store it before it is changed. The the process is atomic.
Why Disable Interrupts
Priority Inversion can still cause deadlock if without disable_interrupts.
There are two processes P1 and P2. P1 requires resource A and is currently holding it. Now P2 with higher priority kicks in and ask for resource A.
Since P2 is super important, it keeps spinning and ask for resource A. P1 never has a chance to release A and P2 never gets A. Finally results a deadlock.
The solution is including a disableInterrupts() implemented by hardware.