The book Operating System Principles by Silberschatz, Galvin and Gagne contains the following definition for the TestAndSet() instruction in the chapter on synchronization:
boolean TestAndSet(boolean *target) {
boolean rv = *target;
*target = TRUE;
return rv;
}
An implementation of mutual-exclusion using the above instruction is also provided as follows:
do {
while(TestAndSetLock(&lock))
; // do nothing
// critical section
lock = FALSE;
// remainder section
} while(TRUE);
Now, how is mutual exclusion achieved if there is no condition for setting target to TRUE?
Consider the following situation, process P0 sets the shared variable lock to TRUE and enters its critical section. Another process P1 calls TestAndSet() in the while loop above, it returns TRUE (since P0 has the lock) while unconditionally setting lock to FALSE. The second time TestAndSet() is called in the while loop it will return FALSE and P1 enters its critical section even though P0 is in its critical section. Mutual-exclusion is then violated.
I did some searching and stumbled upon a paper by Mithun Acharya and Robert Funderlic (of the North Carolina State University CS department) which contains the following alternative definition of TestAndSet():
boolean Test-and-Set(boolean target)
begin
if(target == false):
target = true;
return target;
end
This makes much more sense to me, I included it for comparison and also because the paper lists the book by Silberschatz as one of its references.
I just don't understand how the definition I found in my text book (the one I provided first) can be used to acheieve mutual exclusion, can anyone help?