For a uni-processor, the lock algorithm is pretty simple.
Lock(threadID) {
Disable Interrupts
If lock is already owned by same thread{
Restore Interrupts
return
}
if lock is free {
make lock busy
set current thread as the owner of the lock
}
else {
add threadID to the lock queue.
}
Restore Interrupts
return
}
But how do we implement this code in multiprocessor/multicore systems. What if 2 cores/procs try to give the same lock to different processes.
Mutexes are generally implemented with atomic operations on a single memory value. For instance, a lock can be a single word that is free when 0
and locked when 1
. To acquire the lock, the processor will lock the memory bus (so no other processors can read or write to memory), read the most-current value of the word, set it to 1
if it is 0
, and unlock the memory bus. To unlock, the word can be set to 0
.
That's a simple example that doesn't address what happens when the lock is contended. Different OSs handle that using different mechanisms. Linux uses something called futexes. I'm not sure what Windows or Macs do.
Although the algorithm you posted is correct, non-kernel code can't disable CPU interrupts, so user-space code will tend to use atomic operations even on a single core.