i
i
i
i
i
i
i
i
8.4. EXERCISES 297
(b) fetch-inc: LL R, L // R = mem[L]
add R, R, #1 // R = R + 1
SC L, R // mem[L] = R
bscfail R, fetch-inc // loop back if SC fails
(c) atomic-exch: ll R2, L // R2 = mem[L]
sc L, R // mem[L] = R
bscfail R, atomic-exch // loop back if SC fails
mov R, R2 // R = R2
Note that the mov instruction is purposedly placed after the sc, which is important to
make sure that the sc is more likely to succeed. It is safe to do that because the value
to be assigned to R is in the register R2, and hence can no longer be affected by an
intervention or invalidation of another processor.
3. Implementing locks. Implement lock() and unlock() directly using the atomic ex-
change instruction. The instruction atomic exch R, L performs an atomic sequence of
swapping/exchanging the value held in register R and location L. Use the following conven-
tion: a value of “1” indicates that a lock is currently held by a process, and a value of “0”
indicates that a lock is free. Your implementation should not repeatedly generate bus traffic
when a lock is continuously held by another process.
Answer:
lock: mov R, #1 // R = 1
loop: ld R2, L // R2 = mem[L]
bnz R2, loop // Lock not free, loop back
atomic_exch R, L // exchange R with mem[L]
bnz R, loop // lock attempt fails, loop back
ret // lock successfully acquired, return
unlock: st L, #0 // release the lock
ret
4. Barrier implementation. A proposed solution for implementing the barrier is the following:
BARRIER (Var B: BarVariable, N: integer)
{
if (fetch&add(B,1) == N-1)
B = 0;
else
while (B != 0) {}; // spin until B is zero
}
Describe a correctness problem with the barrier implementation. Then, rewrite the code for
BARRIER() in a way that avoids the correctness problem.
Answer:
The correctness problem occurs when all but last thread have arrived at the barrier spinning on
the while loop. Then the last thread arrives and sets B to 0. The last thread may then continue
to the next barrier with the same name, and immediately increments B. Other threads that are