I'm studying lock/unlock examples and I have a question on Test&Set Here is lock acquire and release logic using Test&Set function.
Think of it as a situation where thread A has a lock and thread B wants to acquire lock. If thread A releases a lock(line 2) after B thread loads a lock variable into the register(line 1), and thread B overwrites the value to 1(line 3), I think it will be possible for thread B to go around an infinite loop in Acquire function, because there is no chance to change lock variable. Am I right?
// In Test&Set function
r = M[addr]; // thread B
M[addr] = 0; // thread A
M[addr] = 1; // thread B
Thanks for your answer.
I considered if Test&Set function is atomic instruction, I don't think this situation will happen because no other instruction intervenes between the two commands, but I wonder if it's right.
Right, this example is assuming the use of an atomic TestAndSet function, as well as the use of an atomic write function in Thread A if the language's memory model requires it. Such functions would use special hardware features to ensure that thread A's write cannot occur between the read and write in thread B.
With atomic operations, one of two things is guaranteed to happen:
Either the write in thread A occurs before the TestAndSet, in which case the TestAndSet sets r to 0, and the final value in M[addr]
is 1. In this case, thread B acquires the lock.
Or, the write in thread A occurs after the TestAndSet, in which case the TestAndSet sets r to 1. In this case thread B does not acquire the lock, but the write in thread A will become visible sometime later, resulting in M[addr]
having the value 0. If the TestAndSet is repeated after this point, it will set r to 0.
Either way, the infinite loop (deadlock) that concerns you is not possible.