Fetch_And_Add(X,i) is an atomic Read-Modify-Write instruction that reads the value of memory location , increments it by the value , and returns the old value of . It is used in the pseudocode shown below to implement a busy-wait lock. is an unsigned integer shared variable initialized to . The value of corresponds to lock being available, while any non-zero value corresponds to the lock being not available.
AcquireLock(L){
while (Fetch_And_Add(L,1))
L = 1;
}
ReleaseLock(L){
L = 0;
}
This implementation
View worked solution
Answer: B
To analyze the behavior of the lock implementation, let us trace the execution with two processes, and , where the shared variable is initially (lock is available):
- attempts to acquire the lock:
- executes
Fetch_And_Add(L, 1). This atomically reads the old value , increments to , and returns . - Since the returned value is , the
whileloop condition is false. successfully acquires the lock and enters the Critical Section (CS).
- executes
- attempts to acquire the lock while is in the CS:
- executes
Fetch_And_Add(L, 1). This reads the current value , increments to , and returns . - Since the returned value is (non-zero), enters the loop body and is about to execute
L = 1;.
- executes
- releases the lock:
- finishes its CS and calls
ReleaseLock(L), which sets . The lock is now conceptually free.
- finishes its CS and calls
- resumes execution:
- now executes its pending loop body statement:
L = 1;. - This overwrites the value of back to .
- now executes its pending loop body statement:
At this point, no process is in the Critical Section, meaning the lock is actually available. However, because , any subsequent call to AcquireLock(L) by any process will read a non-zero value and get stuck in the busy-wait loop. Thus, the implementation fails because can take on a non-zero value when the lock is actually available.
Free practice · Your answers on this page are not saved.
