NICOLAS GUARINI — M. 918670 — [email protected]
Draw the control flow graph (CFG) of the method CriticalProcessExecManager.exec(Process)
given below.
public class CriticalProcessExecManager {
private Random rand = new Random();
class Lock {
boolean lockActive;
Lock() {lockActive = false;}
void lock() {lockActive = true;}
void unlock() {lockActive = false;}
boolean isLocked() {return lockActive;}
}
class Process {
int execCounter = 0;
void exec() {
/* ... do something critical */
execCounter++;
}
}
void exec(Process proc) {
Lock l = new Lock();
int counter;
do {
if (l.isLocked()) {
throw new RuntimeException("Locking error 1");
}
l.lock();
counter = proc.execCounter;
if (rand.nextBoolean()) {
proc.exec();
if (!l.isLocked()) {
throw new RuntimeException("Locking error 2");
}
l.unlock();
}
} while (counter != proc.execCounter);
if (!l.isLocked()) {
throw new RuntimeException("Locking error 3");
}
l.unlock();
}
}
Is there any CFG path that leads to throwing the exceptions "Locking error 1", "Locking error 2" and "Locking error 3"? (Show a CFG path for each of the three exceptions).
Yes, three possible paths are:
Considering the CFG paths that you indicated as answers to the previous question, do they correspond to some program execution in which we can truly observe those exceptions, or are they false alarms?
Analyzing the code it would seem not, given that in all 3 cases the exception is raised if a variable has a different value from the one set immediately before. However, it still makes sense to consider these paths because such situations could happen for reasons that do not depend on the program or its implementation, such as concurrency problems or race conditions, considering the fact that the proposed class seems to be used in multithreading contexts.